From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 740 invoked from network); 2 Jan 1997 09:57:02 -0000 Received: from euclid.skiles.gatech.edu (list@130.207.146.50) by coral.primenet.com.au with SMTP; 2 Jan 1997 09:57:02 -0000 Received: (from list@localhost) by euclid.skiles.gatech.edu (8.7.3/8.7.3) id EAA25755; Thu, 2 Jan 1997 04:57:31 -0500 (EST) Resent-Date: Thu, 2 Jan 1997 04:57:31 -0500 (EST) From: Zefram Message-Id: <21064.199701020958@stone.dcs.warwick.ac.uk> Subject: message display in ZLE To: zsh-workers@math.gatech.edu (Z Shell workers mailing list) Date: Thu, 2 Jan 1997 09:58:32 +0000 (GMT) X-Patch: 176 X-Loop: zefram@dcs.warwick.ac.uk X-Stardate: [-31]8667.07 X-US-Congress: Moronic fuckers Content-Type: text Resent-Message-ID: <"mDwJ-1.0.MI6.AQuoo"@euclid> Resent-From: zsh-workers@math.gatech.edu X-Mailing-List: archive/latest/2699 X-Loop: zsh-workers@math.gatech.edu Precedence: list Resent-Sender: zsh-workers-request@math.gatech.edu -----BEGIN PGP SIGNED MESSAGE----- This patch adds, and uses, a function showmsg(), which displays an arbitrary message below the ZLE buffer and minibuffer. Previously, whereis() and describekeybriefly() both had the code to do this. The reason for making it a separate function is that it's very useful functionality, particularly for error messages, and I anticipate much greater use of it with the ZLE extensions. I've also made it safer -- the code now handles line wrap and unprintable characters correctly. -zefram *** Src/utils.c 1996/12/31 17:08:47 1.50 --- Src/utils.c 1997/01/01 09:52:44 *************** *** 2916,2921 **** --- 2916,2948 ---- return 0; } + /* Create a visibly-represented duplicate of a string. */ + + /**/ + char * + niceztrdup(char const *s) + { + int c, len = strlen(s) * 5; + char *buf = zalloc(len); + char *p = buf, *n, *ret; + + while ((c = *s++)) { + if (itok(c)) + if (c <= Comma) + c = ztokens[c - Pound]; + else + continue; + if (c == Meta) + c = *s++ ^ 32; + n = nicechar(c); + while(*n) + *p++ = *n++; + } + ret = metafy(buf, p - buf, META_DUP); + zfree(buf, len); + return ret; + } + /* Unmetafy and output a string, displaying special characters readably. */ /**/ *************** *** 3047,3058 **** return 0; } ! /* Unmetafy and output a string, double quoting it in its entirety. */ /**/ ! int ! dquotedzputs(char const *s, FILE *stream) { if(isset(CSHJUNKIEQUOTES)) { int inquote = 0; --- 3074,3089 ---- return 0; } ! /* Double-quote a metafied string. */ /**/ ! char * ! dquotedztrdup(char const *s) { + int len = strlen(s) * 4 + 2; + char *buf = zalloc(len); + char *p = buf, *ret; + if(isset(CSHJUNKIEQUOTES)) { int inquote = 0; *************** *** 3066,3104 **** case '$': case '`': if(inquote) { ! if(fputc('"', stream) < 0) ! return EOF; inquote = 0; } ! if(fputc('\\', stream) < 0) ! return EOF; ! if(fputc(c, stream) < 0) ! return EOF; break; default: if(!inquote) { ! if(fputc('"', stream) < 0) ! return EOF; inquote = 1; } ! if(c == '\n') { ! if(fputc('\\', stream) < 0) ! return EOF; ! } ! if(fputc(c, stream) < 0) ! return EOF; break; } } ! if (inquote) { ! if(fputc('"', stream) < 0) ! return EOF; ! } } else { int pending = 0; ! if(fputc('"', stream) < 0) ! return EOF; while(*s) { int c = *s++; --- 3097,3125 ---- case '$': case '`': if(inquote) { ! *p++ = '"'; inquote = 0; } ! *p++ = '\\'; ! *p++ = c; break; default: if(!inquote) { ! *p++ = '"'; inquote = 1; } ! if(c == '\n') ! *p++ = '\\'; ! *p++ = c; break; } } ! if (inquote) ! *p++ = '"'; } else { int pending = 0; ! *p++ = '"'; while(*s) { int c = *s++; *************** *** 3106,3144 **** c = *s++ ^ 32; switch(c) { case '\\': ! if(pending) { ! if(fputc('\\', stream) < 0) ! return EOF; ! } ! if(fputc('\\', stream) < 0) ! return EOF; pending = 1; break; case '"': case '$': case '`': ! if(pending) { ! if(fputc('\\', stream) < 0) ! return EOF; ! } ! if(fputc('\\', stream) < 0) ! return EOF; /* fall through */ default: ! if(fputc(c, stream) < 0) ! return EOF; pending = 0; break; } } ! if(pending) { ! if(fputc('\\', stream) < 0) ! return EOF; ! } ! if(fputc('"', stream) < 0) ! return EOF; } ! return 0; } /**/ --- 3127,3170 ---- c = *s++ ^ 32; switch(c) { case '\\': ! if(pending) ! *p++ = '\\'; ! *p++ = '\\'; pending = 1; break; case '"': case '$': case '`': ! if(pending) ! *p++ = '\\'; ! *p++ = '\\'; /* fall through */ default: ! *p++ = c; pending = 0; break; } } ! if(pending) ! *p++ = '\\'; ! *p++ = '"'; } ! ret = metafy(buf, p - buf, META_DUP); ! zfree(buf, len); ! return ret; ! } ! ! /* Unmetafy and output a string, double quoting it in its entirety. */ ! ! /**/ ! int ! dquotedzputs(char const *s, FILE *stream) ! { ! char *d = dquotedztrdup(s); ! int ret = zputs(d, stream); ! ! zsfree(d); ! return ret; } /**/ *************** *** 3311,3316 **** --- 3337,3351 ---- memcpy(r, s, len); r[len] = '\0'; return r; + } + + /* Append a string to an allocated string, reallocating to make room. */ + + /**/ + char * + appstr(char *base, char const *append) + { + return strcat(realloc(base, strlen(base) + strlen(append) + 1), append); } /* Change directory, without following symlinks. Returns 0 on success, -1 * *** Src/Zle/zle.h 1997/01/01 06:18:27 1.5 --- Src/Zle/zle.h 1997/01/01 09:05:01 *************** *** 79,84 **** --- 79,89 ---- * list. */ ZLEXTERN int showinglist; + /* Non-zero if ALWAYS_LAST_PROMPT has been used, meaning that the * + * screen below the buffer display should not be cleared by * + * refresh(), but should be by trashzle(). */ + ZLEXTERN int clearflag; + /* flags associated with last command */ ZLEXTERN int lastcmd; *** Src/Zle/zle_keymap.c 1997/01/01 06:50:23 1.2 --- Src/Zle/zle_keymap.c 1997/01/01 09:39:25 *************** *** 376,385 **** { Keymap km = openkeymap(name); ! if(!km && !fb) ! return 1; ! if(!km) km = openkeymap(name = ".safe"); curkeymapname = name; curkeymap = km; return 0; --- 376,392 ---- { Keymap km = openkeymap(name); ! if(!km) { ! char *nm = niceztrdup(name); ! char *msg = tricat("No such keymap `", nm, "'"); ! ! zsfree(nm); ! showmsg(msg); ! zsfree(msg); ! if(!fb) ! return 1; km = openkeymap(name = ".safe"); + } curkeymapname = name; curkeymap = km; return 0; *** Src/Zle/zle_main.c 1996/12/26 19:13:33 1.9 --- Src/Zle/zle_main.c 1997/01/01 10:05:15 *************** *** 374,380 **** addedsuffix = complexpect = vichgflag = 0; viinsbegin = 0; statusline = NULL; - selectkeymap("main", 1); if ((s = (unsigned char *)getlinknode(bufstack))) { setline((char *)s); zsfree((char *)s); --- 374,379 ---- *************** *** 396,403 **** alarm(tmout); zleactive = 1; resetneeded = 1; - refresh(); errflag = retflag = 0; while (!done && !errflag) { struct zlecmd *zc; --- 395,403 ---- alarm(tmout); zleactive = 1; resetneeded = 1; errflag = retflag = 0; + selectkeymap("main", 1); + refresh(); while (!done && !errflag) { struct zlecmd *zc; *************** *** 591,603 **** return 0; } - extern int clearflag; - /**/ void describekeybriefly(void) { ! char *seq, *str; int func; if (statusline) --- 591,601 ---- return 0; } /**/ void describekeybriefly(void) { ! char *seq, *str, *msg, *is; int func; if (statusline) *************** *** 609,629 **** statusline = NULL; if(!*seq) return; ! trashzle(); ! clearflag = (isset(USEZLE) && termok && ! (isset(ALWAYSLASTPROMPT) && zmult == 1)) || ! (unset(ALWAYSLASTPROMPT) && zmult != 1); ! printbind(seq, shout); ! fprintf(shout, " is "); if (func == -1) ! printbind(str, shout); ! else ! fputs(ZLEGETCMD(func)->name, shout); ! if (clearflag) ! putc('\r', shout), tcmultout(TCUP, TCMULTUP, nlnct); else ! putc('\n', shout); ! showinglist = 0; } #define MAXFOUND 4 --- 607,622 ---- statusline = NULL; if(!*seq) return; ! msg = bindztrdup(seq); ! msg = appstr(msg, " is "); if (func == -1) ! is = bindztrdup(str); else ! is = niceztrdup(ZLEGETCMD(func)->name); ! msg = appstr(msg, is); ! zsfree(is); ! showmsg(msg); ! zsfree(msg); } #define MAXFOUND 4 *************** *** 631,636 **** --- 624,630 ---- struct findfunc { int func; int found; + char *msg; }; static void *************** *** 641,650 **** if(func != ff->func) return; if (!ff->found++) ! fputs("on", shout); if(ff->found <= MAXFOUND) { ! putc(' ', shout); ! printbind(seq, shout); } } --- 635,647 ---- if(func != ff->func) return; if (!ff->found++) ! ff->msg = appstr(ff->msg, " is on"); if(ff->found <= MAXFOUND) { ! char *b = bindztrdup(seq); ! ! ff->msg = appstr(ff->msg, " "); ! ff->msg = appstr(ff->msg, b); ! zsfree(b); } } *************** *** 657,677 **** if ((ff.func = executenamedcommand("Where is: ")) == -1) return; ff.found = 0; ! trashzle(); ! clearflag = (isset(USEZLE) && termok && ! (isset(ALWAYSLASTPROMPT) && zmult == 1)) || ! (unset(ALWAYSLASTPROMPT) && zmult != 1); ! fprintf(shout, "%s is ", ZLEGETCMD(ff.func)->name); scankeymap(curkeymap, 1, scanfindfunc, &ff); if (!ff.found) ! fputs("not bound to any key", shout); else if(ff.found > MAXFOUND) ! fputs(" et al", shout); ! if (clearflag) ! putc('\r', shout), tcmultout(TCUP, TCMULTUP, nlnct); ! else ! putc('\n', shout); ! showinglist = 0; } /**/ --- 654,667 ---- if ((ff.func = executenamedcommand("Where is: ")) == -1) return; ff.found = 0; ! ff.msg = niceztrdup(ZLEGETCMD(ff.func)->name); scankeymap(curkeymap, 1, scanfindfunc, &ff); if (!ff.found) ! ff.msg = appstr(ff.msg, " is not bound to any key"); else if(ff.found > MAXFOUND) ! ff.msg = appstr(ff.msg, " et al"); ! showmsg(ff.msg); ! zsfree(ff.msg); } /**/ *** Src/Zle/zle_refresh.c 1996/12/24 02:10:05 1.2 --- Src/Zle/zle_refresh.c 1997/01/01 08:55:54 *************** *** 191,197 **** oput_rpmpt, /* whether displayed right-prompt last time */ oxtabs, /* oxtabs - tabs expand to spaces if set */ numscrolls, onumscrolls; - extern int clearflag; /* set to non-zero if alwayslastprompt used */ /**/ void --- 191,196 ---- *** Src/Zle/zle_tricky.c 1996/12/31 17:08:56 1.6 --- Src/Zle/zle_tricky.c 1997/01/01 08:57:29 *************** *** 2087,2097 **** } } - /* This is non-zero if the cursor was moved up after showing a list * - * of completions (with alwayslastprompt). */ - - int clearflag; - /**/ void docompletion(char *s, int lst, int incmd, int untokenized) --- 2087,2092 ---- *************** *** 3443,3451 **** #ifdef DEBUG /* Sanity check */ if(!validlist) { ! trashzle(); ! fputs("BUG: listmatches called with bogus list\n", shout); ! showinglist = 0; return; } #endif --- 3438,3444 ---- #ifdef DEBUG /* Sanity check */ if(!validlist) { ! showmsg("BUG: listmatches called with bogus list"); return; } #endif *** Src/Zle/zle_utils.c 1996/12/31 02:44:26 1.4 --- Src/Zle/zle_utils.c 1997/01/01 09:33:01 *************** *** 335,348 **** return c; } ! /* Display a metafied string, keybinding-style. */ /**/ ! int ! printbind(char *str, FILE *stream) { ! int c, ret, len = 1; ! char *buf, *ptr; for(ptr = str; *ptr; ptr++) { c = *ptr == Meta ? STOUC(*++ptr) ^ 32 : STOUC(*ptr); --- 335,348 ---- return c; } ! /* Format a string, keybinding style. */ /**/ ! char * ! bindztrdup(char *str) { ! int c, len = 1; ! char *buf, *ptr, *ret; for(ptr = str; *ptr; ptr++) { c = *ptr == Meta ? STOUC(*++ptr) ^ 32 : STOUC(*ptr); *************** *** 375,381 **** *ptr++ = c; } *ptr = 0; ! ret = dquotedzputs(buf, stream); zsfree(buf); return ret; } --- 375,430 ---- *ptr++ = c; } *ptr = 0; ! ret = dquotedztrdup(buf); zsfree(buf); return ret; + } + + /* Display a metafied string, keybinding-style. */ + + /**/ + int + printbind(char *str, FILE *stream) + { + char *b = bindztrdup(str); + int ret = zputs(b, stream); + + zsfree(b); + return ret; + } + + /* Display a message where the completion list normally goes. * + * The message must be metafied. */ + + /**/ + void + showmsg(char const *msg) + { + char const *p; + int up = 0, cc = 0, c; + + trashzle(); + clearflag = isset(USEZLE) && termok && isset(ALWAYSLASTPROMPT); + + for(p = msg; (c = *p); p++) { + if(c == Meta) + c = *++p ^ 32; + if(c == '\n') { + putc('\n', shout); + up += 1 + cc / columns; + cc = 0; + } else { + char const *n = nicechar(c); + fputs(n, shout); + cc += strlen(n); + } + } + up += cc / columns; + + if (clearflag) { + putc('\r', shout); + tcmultout(TCUP, TCMULTUP, up + nlnct); + } else + putc('\n', shout); + showinglist = 0; } -----BEGIN PGP SIGNATURE----- Version: 2.6.2 iQCVAwUBMso6SHD/+HJTpU/hAQEo8AP+OQ+KO+8Si5fdcVLnF1jTxAlAzP1hjVAL vydwA6JFbjN8yIdyQdPuyo4f5ePTHdv3B6Sc2NAfoIQmgg+TK4///ulyV+1sIzc6 FgGdsqWhxgqQuwqxG2Xk2QaafvX+slh+OO4zRaWaZOvnO+ayevnq5kdJrIjLnYOH qHjjAwrOrg0= =tvAX -----END PGP SIGNATURE-----