From 0bd9750710cdbab80cfb4036dd87af20afe1552f Mon Sep 17 00:00:00 2001 From: markus schnalke Date: Sat, 5 May 2012 11:48:11 +0200 Subject: [PATCH] prompter: Various rework. 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 | 165 +++++++++++++++++++++++------------------ uip/prompter.c | 214 ++++++++++++++--------------------------------------- 2 files changed, 148 insertions(+), 231 deletions(-) diff --git a/man/prompter.man1 b/man/prompter.man1 index 01b468c..4d701c6 100644 --- a/man/prompter.man1 +++ b/man/prompter.man1 @@ -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 will cause the whole component -to be left out. Otherwise, a `\\' preceding a 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 diff --git a/uip/prompter.c b/uip/prompter.c index 024f604..e1f0bff 100644 --- a/uip/prompter.c +++ b/uip/prompter.c @@ -13,52 +13,27 @@ #include #include -#include - -#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); -} -- 1.7.10.4