prompter: Various rework.
authormarkus schnalke <meillo@marmaro.de>
Sat, 5 May 2012 09:48:11 +0000 (11:48 +0200)
committermarkus schnalke <meillo@marmaro.de>
Sat, 5 May 2012 09:48:11 +0000 (11:48 +0200)
Removed -kill and -erase as they are not needed anymore today.
Removed -doteof/-nodoteof. -nodoteof had been the default already.
Made the yet hidden switches -body/-nobody visible, but with a slightly
different meaning. See recent changes in the man page prompter(1) for
details. (Eventually, one can have mutt-like message composing.)

man/prompter.man1
uip/prompter.c

index 01b468c..4d701c6 100644 (file)
@@ -3,33 +3,29 @@
 .\"
 .TH PROMPTER %manext1% "%nmhdate%" MH.6.8 [%nmhversion%]
 .SH NAME
-prompter \- prompting editor front-end for nmh
+prompter \- prompting editor front-end for mmh
 .SH SYNOPSIS
 .HP 5
 .na
 .B prompter
-.RB [ \-erase
-.IR chr ]
-.RB [ \-kill
-.IR chr ]
 .RB [ \-prepend " | " \-noprepend ]
 .RB [ \-rapid " | " \-norapid ]
-.RB [ \-doteof " | " \-nodoteof ]
+.RB [ \-body " | " \-nobody ]
 .I file
 .RB [ \-Version ]
 .RB [ \-help ]
 .ad
 .SH DESCRIPTION
 .B Prompter
-is an editor front\-end for
-.B nmh
+is an editor front-end for
+.B mmh
 which allows rapid
 composition of messages.  This program is not normally invoked directly by
-users but takes the place of an editor and acts as an editor front\-end.
-It operates on an RFC\-822 style message draft skeleton specified by
+users but takes the place of an editor and acts as an editor front-end.
+It operates on an RFC-822 style message draft skeleton specified by
 .IR file ,
 normally provided by the
-.B nmh
+.B mmh
 commands
 .BR comp ,
 .BR dist ,
@@ -39,9 +35,7 @@ or
 .PP
 .B Prompter
 is particularly useful when composing messages over slow
-network or modem lines.  It is an
-.B nmh program in that it can have
-its own profile entry with switches, but it is not invoked directly by
+network or modem lines.  It is hardly invoked directly by
 the user.  The commands
 .BR comp ,
 .BR dist ,
@@ -49,33 +43,43 @@ the user.  The commands
 and
 .B repl
 invoke
-.B prompter as an editor, either when invoked with
+.B prompter
+as an editor, either when invoked with
 .B \-editor
 .IR prompter ,
 or by the profile entry `Editor:\ prompter',
 or when given the command
-.B edit
-.B prompter
+.B edit prompter
 at the `What now?' prompt.
 .PP
 For each empty component
-.B prompter finds in the draft, the user
-is prompted for a response; A <RETURN> will cause the whole component
-to be left out.  Otherwise, a `\\' preceding a <RETURN> will continue
+.B prompter
+finds in the draft, the user
+is prompted for a response. An empty response will cause the whole component
+to be left out.  Otherwise, a `\\' preceding the Newline will continue
 the response on the next line, allowing for multiline components.
 Continuation lines
 .B must
 begin with a space or tab.
 .PP
-Each non\-empty component is copied to the draft and displayed on the
+Each non-empty component is copied to the draft and displayed on the
 terminal.
 .PP
 The start of the message body is denoted by a blank line or a line
-of dashes.  If the body is non\-empty, the prompt, which isn't written
-to the file, is
+of dashes.
+Unless
+.B \-nobody
+is specified, the user is queried to enter the message body.
+If the body of the draft is non-empty, the typed-in text will be prepended
+or appended to the existing body, depending on the
+.B \-prepend
+and
+.B \-noprepend
+switches.
+In these cases, the prompt (which isn't written to the file) is
 .PP
 .RS 5
---------Enter additional text
+\-\-\-\-\-\-\-\-Enter additional text
 .RE
 .PP
 or (if
@@ -83,60 +87,61 @@ or (if
 was given)
 .PP
 .RS 5
---------Enter initial text
+\-\-\-\-\-\-\-\-Enter initial text
 .RE
 .PP
-Message\-body typing is terminated with an end\-of\-file (usually
-CTRL\-D).  With the
-.B \-doteof
-switch, a period on a line all by itself
-also signifies end\-of\-file.  At this point control is returned to
+Message-body typing is terminated with an end-of-file (usually
+CTRL-D).
+At this point control is returned to
 the calling program, where the user is asked `What now?'.
 See
 .B whatnow (1)
 for the valid options to this query.
 .PP
 By using the
+.B \-nobody
+switch, the user is only queried to fill in header fields, but not to enter
+any body text.
+Note, that the
+.BR \-body and \-nobody
+switches had already existed already in
+.B nmh
+in undocumented/hidden form,
+but with a slightly different meaning.
+Back then,
+.B "prompter \-nobody
+would change the draft to have an empty body,
+by ignoring any existing body and not querying the user for body text.
+.PP
+By using the
 .B \-prepend
-switch, the user can add type\-in to the
+switch, the user can add type-in to the
 beginning of the message body and have the rest of the body follow.
-This is useful for the
-.B forw
-command.
+With
+.B \-noprepend
+the typed-in text is appended to the message body.
 .PP
 By using the
 .B \-rapid
 switch, if the draft already contains text in
-the message\-body, it is not displayed on the user's terminal.  This is
-useful for low\-speed terminals.
+the message-body, it is not displayed on the user's terminal.  This is
+useful for low-speed terminals.
 .PP
-The line editing characters for kill and erase may be specified by the
-user via the arguments
-.B \-kill
-.I chr
-and
-.B \-erase
-.IR chr ,
-where
-.I chr
-may be a character; or `\\nnn', where `nnn' is the octal value for
-the character.
-.PP
-An interrupt (usually CTRL\-C) during component typing will abort
+An interrupt (usually CTRL-C) during component typing will abort
 .B prompter
 and the
-.B nmh
+.B mmh
 command that invoked it.  An interrupt
-during message\-body typing is equivalent to CTRL\-D, for historical
-reasons.  This means that
+during message-body typing is equivalent to CTRL-D, for historical
+reasons and to avoid losing the typed-in message text.  This means that
 .B prompter
-should finish up and exit.
+should finish up and exit, usually putting the user back to the
+Whatnow prompt.
 .PP
-The first non\-flag argument to
-.B prompter is taken as the name of
-the draft file, and subsequent non\-flag arguments are ignored.
-.\" (\fIRepl\fR invokes editors with two file arguments:
-.\" the draft file name and the replied\-to message file name.)
+The first non-flag argument to
+.B prompter
+is taken as the name of
+the draft file, and subsequent non-flag arguments are ignored.
 
 .SH FILES
 .fc ^ ~
@@ -151,7 +156,7 @@ the draft file, and subsequent non\-flag arguments are ignored.
 .nf
 .ta 2.4i
 .ta \w'ExtraBigProfileName  'u
-prompter\-next:        To name the editor to be used on exit from .B prompter
+prompter\-next:        The editor to be used on exit from \fBprompter\fP
 ^Msg\-Protect:~^To set mode when creating a new draft
 .fi
 
@@ -160,9 +165,9 @@ comp(1), dist(1), forw(1), repl(1), whatnow(1)
 
 .SH DEFAULTS
 .nf
+.RB ` \-body '
 .RB ` \-prepend '
 .RB ` \-norapid '
-.RB ` \-nodoteof '
 .fi
 
 .SH CONTEXT
@@ -170,26 +175,40 @@ None
 
 .SH "HELPFUL HINTS"
 The
-.B \-rapid
-option is particularly useful with
-.BR forw ,
-and
 .B \-noprepend
-is useful with
+switch is particularly useful with
 .B comp
 .BR \-use .
 .PP
 The user may wish to link
-.B prompter under several names (e.g.,
+.B prompter
+under several names (e.g.,
 `rapid') and give appropriate switches in the profile entries
 under these names (e.g., `rapid: -rapid').  This facilitates
 invoking prompter differently for different
-.B nmh
+.B mmh
 commands (e.g.,
 `forw: -editor rapid').
-
-.SH BUGS
-.B Prompter
-uses
-.BR stdio (3),
-so it will lose if you edit files with nulls in them.
+.PP
+Former
+.B mutt
+users might find it useful to create a shell script
+.B hprompter
+containing:
+.PP
+.RS 5
+.nf
+prompter \-nobody \-rapid "$1"
+vi "$1"
+.fi
+.RE
+.LP
+and use that as the default editor for
+.B comp
+by adding a profile entry like:
+.PP
+.RS 5
+.nf
+comp: \-editor hprompter
+.fi
+.RE
index 024f604..e1f0bff 100644 (file)
 #include <signal.h>
 #include <setjmp.h>
 
-#include <termios.h>
-
-#define QUOTE '\\'
-
-#ifndef CKILL
-# define CKILL '@'
-#endif
-
-#ifndef CERASE
-# define CERASE '#'
-#endif
-
 static struct swit switches[] = {
-#define ERASESW  0
-       { "erase chr", 0 },
-#define KILLSW  1
-       { "kill chr", 0 },
-#define PREPSW  2
+#define PREPSW  0
        { "prepend", 0 },
-#define NPREPSW  3
+#define NPREPSW  1
        { "noprepend", 2 },
-#define RAPDSW  4
+#define RAPDSW  2
        { "rapid", 0 },
-#define NRAPDSW  5
+#define NRAPDSW  3
        { "norapid", 2 },
-#define BODYSW  6
-       { "body", -4 },
-#define NBODYSW  7
-       { "nobody", -6 },
-#define DOTSW  8
-       { "doteof", 0 },
-#define NDOTSW  9
-       { "nodoteof", 2 },
-#define VERSIONSW 10
+#define BODYSW  4
+       { "body", 0 },
+#define NBODYSW  5
+       { "nobody", 2 },
+#define VERSIONSW 6
        { "Version", 0 },
-#define HELPSW  11
+#define HELPSW  7
        { "help", 0 },
        { NULL, 0 }
 };
 
 
-static struct termios tio;
-#define ERASE tio.c_cc[VERASE]
-#define KILL  tio.c_cc[VKILL]
-#define INTR  tio.c_cc[VINTR]
-
 static int wtuser = 0;
 static int sigint = 0;
 static jmp_buf sigenv;
@@ -67,18 +42,16 @@ static jmp_buf sigenv;
 ** prototypes
 */
 int getln(char *, int);
-static int chrcnv(char *);
-static void chrdsp(char *, char);
 static void intrser(int);
 
 
 int
 main(int argc, char **argv)
 {
-       int body = 1, prepend = 1, rapid = 0;
-       int doteof = 0, fdi, fdo, i, state;
-       char *cp, *drft = NULL, *erasep = NULL;
-       char *killp = NULL, name[NAMESZ], field[BUFSIZ];
+       int qbody = 1, prepend = 1, rapid = 0;
+       int fdi, fdo, i, state;
+       char *cp, *drft = NULL;
+       char name[NAMESZ], field[BUFSIZ];
        char buffer[BUFSIZ], tmpfil[BUFSIZ];
        char **arguments, **argp;
        FILE *in, *out;
@@ -95,7 +68,7 @@ main(int argc, char **argv)
        arguments = getarguments(invo_name, argc, argv, 1);
        argp = arguments;
 
-       while ((cp = *argp++))
+       while ((cp = *argp++)) {
                if (*cp == '-') {
                        switch (smatch(++cp, switches)) {
                        case AMBIGSW:
@@ -114,17 +87,6 @@ main(int argc, char **argv)
                                print_version(invo_name);
                                done(1);
 
-                       case ERASESW:
-                               if (!(erasep = *argp++) || *erasep == '-')
-                                       adios(NULL, "missing argument to %s",
-                                                       argp[-2]);
-                               continue;
-                       case KILLSW:
-                               if (!(killp = *argp++) || *killp == '-')
-                                       adios(NULL, "missing argument to %s",
-                                                       argp[-2]);
-                               continue;
-
                        case PREPSW:
                                prepend++;
                                continue;
@@ -140,22 +102,16 @@ main(int argc, char **argv)
                                continue;
 
                        case BODYSW:
-                               body++;
+                               qbody++;
                                continue;
                        case NBODYSW:
-                               body = 0;
-                               continue;
-
-                       case DOTSW:
-                               doteof++;
-                               continue;
-                       case NDOTSW:
-                               doteof = 0;
+                               qbody = 0;
                                continue;
                        }
                } else if (!drft) {
                        drft = cp;
                }
+       }
 
        if (!drft)
                adios(NULL, "usage: %s [switches] file", invo_name);
@@ -168,42 +124,6 @@ main(int argc, char **argv)
        chmod(tmpfil, 0600);
        strncpy(tmpfil, tfile, sizeof(tmpfil));
 
-       /*
-       ** Are we changing the kill or erase character?
-       */
-       if (killp || erasep) {
-               cc_t save_erase, save_kill;
-
-               /* get the current terminal attributes */
-               tcgetattr(0, &tio);
-
-               /* save original kill, erase character for later */
-               save_kill = KILL;
-               save_erase = ERASE;
-
-               /* set new kill, erase character in terminal structure */
-               KILL = killp ? chrcnv(killp) : save_kill;
-               ERASE = erasep ? chrcnv(erasep) : save_erase;
-
-               /* set the new terminal attributes */
-                tcsetattr(0, TCSADRAIN, &tio);
-
-               /* print out new kill erase characters */
-               chrdsp("erase", ERASE);
-               chrdsp(", kill", KILL);
-               chrdsp(", intr", INTR);
-               putchar('\n');
-               fflush(stdout);
-
-               /*
-               ** We set the kill and erase character back to original
-               ** setup in terminal structure so we can easily
-               ** restore it upon exit.
-               */
-               KILL = save_kill;
-               ERASE = save_erase;
-       }
-
        sigint = 0;
        SIGNAL2(SIGINT, intrser);
 
@@ -225,7 +145,7 @@ main(int argc, char **argv)
                                        break;
 
                        /* If so, just add header line to draft */
-                       if (*cp++ != '\n' || *cp != 0) {
+                       if (*cp++ != '\n' || *cp) {
                                printf("%s:%s", name, field);
                                fprintf(out, "%s:%s", name, field);
                                while (state == FLDPLUS) {
@@ -241,13 +161,10 @@ main(int argc, char **argv)
                                i = getln(field, sizeof(field));
                                if (i == -1) {
 abort:
-                                       if (killp || erasep) {
-                                               tcsetattr(0, TCSADRAIN, &tio);
-                                       }
                                        unlink(tmpfil);
                                        done(1);
                                }
-                               if (i != 0 || (field[0] != '\n' && field[0] != 0)) {
+                               if (i || (field[0]!='\n' && field[0]!='\0')) {
                                        fprintf(out, "%s:", name);
                                        do {
                                                if (field[0] != ' ' && field[0] != '\t')
@@ -260,55 +177,58 @@ abort:
                        }
 
                        if (state == FLDEOF) {  /* moby hack */
+                               /* draft has no body separator; only headers */
                                fprintf(out, "--------\n");
-                               printf("--------\n");
-                               if (!body)
+                               if (!qbody)
                                        break;
-                               goto no_body;
+                               printf("--------\n");
+                               goto has_no_body;
                        }
                        continue;
 
                case BODY:
                case BODYEOF:
                case FILEEOF:
-                       if (!body)
-                               break;
                        fprintf(out, "--------\n");
-                       if (field[0] == 0 || !prepend)
-                               printf("--------\n");
-                       if (field[0]) {
-                               if (prepend && body) {
-                                       printf("\n--------Enter initial text\n\n");
+                       if (qbody) {
+                               if (!*field) {
+                                       printf("--------\n");
+                                       goto has_no_body;
+                               }
+
+                               if (prepend) {
+                                       printf("--------Enter initial text\n");
                                        fflush(stdout);
                                        for (;;) {
                                                getln(buffer, sizeof(buffer));
-                                               if (doteof && buffer[0] == '.' && buffer[1] == '\n')
-                                                       break;
-                                               if (buffer[0] == 0)
+                                               if (!*buffer)
                                                        break;
                                                fprintf(out, "%s", buffer);
                                        }
+                               } else {
+                                       printf("--------\n");
                                }
-
-                               do {
-                                       fprintf(out, "%s", field);
-                                       if (!rapid && !sigint)
-                                               printf("%s", field);
-                               } while (state == BODY && (state = m_getfld(state, name, field, sizeof(field), in)));
-                               if (prepend || !body)
-                                       break;
-                               else
-                                       printf ("\n--------Enter additional text\n\n");
                        }
-no_body:
+
+                       do {
+                               fprintf(out, "%s", field);
+                               if (!rapid && !sigint)
+                                       printf("%s", field);
+                       } while (state == BODY &&
+                                       (state = m_getfld(state, name,
+                                       field, sizeof(field), in)));
+
+                       if (prepend || !qbody)
+                               break;
+
+                       printf("--------Enter additional text\n");
+has_no_body:
                        fflush(stdout);
                        for (;;) {
                                getln(field, sizeof(field));
-                               if (doteof && field[0] == '.' && field[1] == '\n')
-                                       break;
-                               if (field[0] == 0)
+                               if (!*field)
                                        break;
-                                fprintf(out, "%s", field);
+                               fprintf(out, "%s", field);
                        }
                        break;
 
@@ -318,7 +238,7 @@ no_body:
                break;
        }
 
-       if (body)
+       if (qbody)
                printf("--------\n");
 
        fflush(stdout);
@@ -326,10 +246,6 @@ no_body:
        fclose(out);
        SIGNAL(SIGINT, SIG_IGN);
 
-       if (killp || erasep) {
-                tcsetattr(0, TCSADRAIN, &tio);
-       }
-
        if ((fdi = open(tmpfil, O_RDONLY)) == NOTOK)
                adios(tmpfil, "unable to re-open");
        if ((fdo = creat(drft, m_gmprot())) == NOTOK)
@@ -352,7 +268,7 @@ getln(char *buffer, int n)
        char *cp;
 
        cp = buffer;
-       *cp = 0;
+       *cp = '\0';
 
        switch (setjmp(sigenv)) {
        case OK:
@@ -375,20 +291,20 @@ getln(char *buffer, int n)
                        longjmp(sigenv, DONE);
 
                case '\n':
-                       if (cp[-1] == QUOTE) {
+                       if (cp[-1] == '\\') {
                                cp[-1] = c;
                                wtuser = 0;
                                return 1;
                        }
                        *cp++ = c;
-                       *cp = 0;
+                       *cp = '\0';
                        wtuser = 0;
                        return 0;
 
                default:
                        if (cp < buffer + n)
                                *cp++ = c;
-                       *cp = 0;
+                       *cp = '\0';
                }
        }
 }
@@ -401,21 +317,3 @@ intrser(int i)
                longjmp(sigenv, NOTOK);
        sigint++;
 }
-
-
-static int
-chrcnv(char *cp)
-{
-       return (*cp != QUOTE ? *cp : m_atoi(++cp));
-}
-
-
-static void
-chrdsp(char *s, char c)
-{
-       printf("%s ", s);
-       if (c < ' ' || c == 0177)
-               printf("^%c", c ^ 0100);
-       else
-               printf("%c", c);
-}