.\"
.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 ,
.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 ,
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
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 ^ ~
.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
.SH DEFAULTS
.nf
+.RB ` \-body '
.RB ` \-prepend '
.RB ` \-norapid '
-.RB ` \-nodoteof '
.fi
.SH CONTEXT
.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
#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;
** 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;
arguments = getarguments(invo_name, argc, argv, 1);
argp = arguments;
- while ((cp = *argp++))
+ while ((cp = *argp++)) {
if (*cp == '-') {
switch (smatch(++cp, switches)) {
case AMBIGSW:
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;
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);
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);
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) {
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')
}
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;
break;
}
- if (body)
+ if (qbody)
printf("--------\n");
fflush(stdout);
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)
char *cp;
cp = buffer;
- *cp = 0;
+ *cp = '\0';
switch (setjmp(sigenv)) {
case OK:
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';
}
}
}
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);
-}