From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from gatech.edu (gatech.edu [130.207.244.244]) by werple.mira.net.au (8.6.12/8.6.9) with SMTP id KAA09425 for ; Mon, 24 Jul 1995 10:11:08 +1000 Received: from math (math.skiles.gatech.edu) by gatech.edu with SMTP id AA05571 (5.65c/Gatech-10.0-IDA for ); Sun, 23 Jul 1995 20:10:59 -0400 Received: by math (5.x/SMI-SVR4) id AA02869; Sun, 23 Jul 1995 20:07:02 -0400 Resent-Date: Mon, 24 Jul 1995 01:07:46 +0100 (BST) Old-Return-Path: From: Zefram Message-Id: <26311.199507240007@stone.dcs.warwick.ac.uk> Subject: More prompt code changes To: zsh-workers@math.gatech.edu (Z Shell workers mailing list) Date: Mon, 24 Jul 1995 01:07:46 +0100 (BST) X-Loop: zefram@dcs.warwick.ac.uk X-Stardate: [-31]6025.02 Mime-Version: 1.0 Content-Type: text/plain; charset=US-ASCII Content-Transfer-Encoding: 7bit Resent-Message-Id: <"U5Cge3.0.li.cGk4m"@math> Resent-From: zsh-workers@math.gatech.edu X-Mailing-List: archive/latest/265 X-Loop: zsh-workers@math.gatech.edu Precedence: list Resent-Sender: zsh-workers-request@math.gatech.edu -----BEGIN PGP SIGNED MESSAGE----- The patch below makes the following changes to the prompt expansion code: o Removes special treatment of unquoted `\' and `!', so that the only special character (after PROMPT_SUBST has done shell expansion) is `%'. Note that this means that things like %(?.\..) won't work; use a different separator, like %(?:.:). Also see next item. o Adds a `%)' sequence, which expands to `)', so that a literal `)' can appear in the false-text of a %() sequence. o Makes %{...%} sequences nest. o Adds the new form of truncation control (previously discussed and agreed upon, but not implemented). o Makes stradd() display control characters nicely, so that a control character in the current path won't confuse ZLE w.r.t. the size of the prompt. o Fixes a bug that was causing truncation control sequences to remain in effect permanently (the truncation should be reset to "off" at the start of each prompt expansion). o Fixes a bug that was causing problems with things like `%1(?.%[<.].)%~' -- the . embedded in the truncation control sequence was recognised as a separator when the test evaluated false. -zefram *** 1.10 1995/07/23 18:39:16 --- Src/zle_misc.c 1995/07/23 23:51:30 *************** *** 697,729 **** static char *bp; static char *truncstr; ! static int docount, lensb, trunclen; /**/ void stradd(char *d) { ! int dlen = strlen(d); addbufspc(dlen); ! if (trunclen) { ! if (dlen > trunclen) { ! char *t = truncstr + 1; ! int len, tlen; ! tlen = strlen(t); ! addbufspc(tlen); ! len = tlen < trunclen ? trunclen - tlen : 0; ! if (*truncstr == '>') { ! while (len--) pputc(*d++); ! while (*t) pputc(*t++); ! } else { ! while (*t) pputc(*t++); ! d += dlen - len; ! while (len--) pputc(*d++); } ! return; } } ! while (*d) pputc(*d++); } /**/ --- 697,743 ---- static char *bp; static char *truncstr; ! static int dontcount, lensb, trunclen; /**/ void stradd(char *d) { ! int dlen = nicestrlen(d); addbufspc(dlen); ! if (trunclen && dlen > trunclen) { ! char *t = truncstr + 1; ! int len, tlen; ! tlen = strlen(t); ! addbufspc(tlen); ! len = tlen < trunclen ? trunclen - tlen : 0; ! if (*truncstr == '>') { ! while (len-- > 0) { ! if(!isprint(*d)) ! len--; ! npputc(*d++); } ! if(len == -2) ! bp--; ! while (*t) pputc(*t++); ! } else { ! while (*t) pputc(*t++); ! d = strchr(d, 0); ! for(; len > 0; len--) ! if(!isprint(*--d)) ! len--; ! if(len == -1) ! switch(*d) { ! case '\n': *bp++ = 'n'; d++; break; ! case '\t': *bp++ = 't'; d++; break; ! case 0x7f: *bp++ = '?'; d++; break; ! default: *bp++ = (*d++) | 0x40; ! } ! while (*d) npputc(*d++); } + return; } ! while (*d) npputc(*d++); } /**/ *************** *** 732,738 **** { addbufspc(1); *bp++ = d; ! if (docount) lensb++; return 0; } --- 746,752 ---- { addbufspc(1); *bp++ = d; ! if (!dontcount) lensb++; return 0; } *************** *** 745,751 **** if (flag == 0) tputs(tcstr[cap], 1, putshout); else { ! if (docount) { int t0; if (cap == TCSTANDOUTBEG || cap == TCSTANDOUTEND) --- 759,765 ---- if (flag == 0) tputs(tcstr[cap], 1, putshout); else { ! if (!dontcount) { int t0; if (cap == TCSTANDOUTBEG || cap == TCSTANDOUTEND) *************** *** 791,802 **** bracepos = -1; fm = fmin; lensb = 0; ! pmpt = (docount = cnt) ? fm : NULL; bp = bl0 = buf = zalloc(bufspc = 256); bp1 = NULL; clearerr(stdin); putpromptchar(1, '\0'); *lenp = bp - buf; --- 805,817 ---- bracepos = -1; fm = fmin; lensb = 0; ! pmpt = (dontcount = !cnt) ? fm : NULL; bp = bl0 = buf = zalloc(bufspc = 256); bp1 = NULL; clearerr(stdin); + trunclen = 0; putpromptchar(1, '\0'); *lenp = bp - buf; *************** *** 808,818 **** --- 823,835 ---- addbufspc(1); *wp = 0; *bp++ = ' '; + ++*lenp; } if (!*wp && *lenp) { addbufspc(1); (*wp)++; *bp++ = ' '; + ++*lenp; } } } *************** *** 966,972 **** continue; } if (!doprint) ! continue; switch (*fm) { case '~': t0 = finddir(pwd); --- 983,1006 ---- continue; } if (!doprint) ! switch(*fm) { ! case '[': ! while(idigit(*++fm)); ! while(*++fm != ']'); ! continue; ! case '<': ! while(*++fm != '<'); ! continue; ! case '>': ! while(*++fm != '>'); ! continue; ! case 'D': ! if(fm[1]=='{') ! while(*++fm != '}'); ! continue; ! default: ! continue; ! } switch (*fm) { case '~': t0 = finddir(pwd); *************** *** 1015,1021 **** break; case 'h': case '!': ! addbufspc(20); /* OK up to 64 bit numbers */ sprintf(bp, "%d", curhist); bp += strlen(bp); break; --- 1049,1055 ---- break; case 'h': case '!': ! addbufspc(DIGBUFSIZE); sprintf(bp, "%d", curhist); bp += strlen(bp); break; *************** *** 1099,1115 **** if(!*fm) return 0; break; case '{': ! if (docount) { bracepos = bp - buf; - docount = 0; - } break; case '}': ! if (bracepos != -1) { lensb += (bp - buf) - bracepos; bracepos = -1; - docount = 1; } break; case 't': --- 1133,1174 ---- if(!*fm) return 0; break; + case '<': + case '>': + if((trunclen = arg)) { + bp1 = bp; + addbufspc(1); + *bp++ = *fm++; + while (*fm && *fm != *bp1) { + if (*fm == '\\' && fm[1]) + ++fm; + addbufspc(1); + *bp++ = *fm++; + } + addbufspc(1); + *bp = '\0'; + zsfree(truncstr); + truncstr = ztrdup(bp = bp1); + bp1 = NULL; + } else { + char ch = *fm++; + while(*fm && *fm != ch) { + if (*fm == '\\' && fm[1]) + fm++; + fm++; + } + } + if(!*fm) + return 0; + break; case '{': ! if (!dontcount++) bracepos = bp - buf; break; case '}': ! if (!--dontcount && bracepos != -1) { lensb += (bp - buf) - bracepos; bracepos = -1; } break; case 't': *************** *** 1172,1178 **** stradd("()"); break; case '?': ! addbufspc(20); /* OK up to 64 bit numbers */ sprintf(bp, "%ld", (long)lastval); bp += strlen(bp); break; --- 1231,1237 ---- stradd("()"); break; case '?': ! addbufspc(DIGBUFSIZE); sprintf(bp, "%ld", (long)lastval); bp += strlen(bp); break; *************** *** 1180,1185 **** --- 1239,1248 ---- addbufspc(1); *bp++ = '%'; break; + case ')': + addbufspc(1); + *bp++ = ')'; + break; case '#': addbufspc(1); *bp++ = (geteuid())? '%' : '#'; *************** *** 1226,1242 **** pputc(*fm); break; } ! } else if (*fm == '!' && doprint) { ! addbufspc(20); /* OK up to 64 bit numbers */ ! sprintf(bp, "%d", curhist); ! bp += strlen(bp); ! } else { ! if (fm[0] == '\\' && fm[1]) ! fm++; ! if (doprint) { ! addbufspc(1); ! pputc(*fm); ! } } } --- 1289,1297 ---- pputc(*fm); break; } ! } else if (doprint) { ! addbufspc(1); ! pputc(*fm); } } *************** *** 1247,1269 **** void pputc(char c) { ! if (docount) { if (pmpt == rpmpt) { if (c == '\t' || c == '\n') c = ' '; ! } else { ! if (c == '\t') { ! int t0 = 7 - (7 & (bp - bl0 - lensb)); ! lensb -= t0; ! } else if (c == '\n') { ! *bp++ = c; ! bl0 = bp; ! lensb = 0; ! return; ! } } } *bp++ = c; } /**/ --- 1302,1337 ---- void pputc(char c) { ! if (!dontcount) { if (pmpt == rpmpt) { if (c == '\t' || c == '\n') c = ' '; ! } else if (c == '\t') { ! int t0 = 7 - (7 & (bp - bl0 - lensb)); ! lensb -= t0; ! } else if (c == '\n') { ! *bp++ = c; ! bl0 = bp; ! lensb = 0; ! return; } } *bp++ = c; + } + + /**/ + void + npputc(char c) + { + if(isprint(c)) + *bp++ = c; + else + switch(c) { + case '\n': *bp++ = '\\'; *bp++ = 'n'; break; + case '\t': *bp++ = '\\'; *bp++ = 't'; break; + case 0x7f: *bp++ = '^'; *bp++ = '?'; break; + default: *bp++ = '^'; *bp++ = c | 0x40; break; + } } /**/ *** 1.2 1995/07/21 21:55:53 --- Doc/zshparam.1 1995/07/23 23:00:09 *************** *** 422,427 **** --- 422,433 ---- .PD 0 .RS .TP + .B %% + A `%'. + .TP + .B %) + A `)'. + .TP .B %d .TP .B %/ *************** *** 443,450 **** An integer may follow the '%' to get more than one component. Unless \fB%C\fP is used, tilde expansion is performed first. .TP - .B ! - .TP .B %h .TP .B %! --- 449,454 ---- *************** *** 524,531 **** .B %(x\fI.true-text.false-text\fB)\fP Specifies a ternary expression. The character following the \fBx\fP is arbitrary; the same character is used to separate the text for the ! "true" result from that for the "false" result. Both the separator and ! the right parenthesis may be escaped with a backslash. \fITrue-text\fP and \fIfalse-text\fP may both contain arbitrarily-nested escape sequences, including further ternary expressions. The left parenthesis may be preceded or followed by a positive integer \fIn\fP, --- 528,537 ---- .B %(x\fI.true-text.false-text\fB)\fP Specifies a ternary expression. The character following the \fBx\fP is arbitrary; the same character is used to separate the text for the ! "true" result from that for the "false" result. ! This separator may not appear in the \fItrue-text\fP, except as part of a % ! sequence. A `)' may appear in the \fIfalse-text\fP as `%)'. ! \fITrue-text\fP and \fIfalse-text\fP may both contain arbitrarily-nested escape sequences, including further ternary expressions. The left parenthesis may be preceded or followed by a positive integer \fIn\fP, *************** *** 585,601 **** True if at least \fIn\fP shell constructs were started. .RE .TP .B %[x\fIstring\fB]\fP ! Specifies truncation behaviour. The opening `[' may be preceded or ! followed by an integer, which specifies the maximum permitted length of the various strings that can be displayed in the prompt. If this integer is zero, or missing, truncation is disabled. Truncation is ! initially disabled. The \fIx\fR character indicates whether the start ! or the end of a string is truncated. If it is `>', the start of a ! truncated string is displayed, and the end removed. If it is anything ! else, or if there is no character between the `[' and `]', the end of a ! truncated string is displayed. The \fIstring\fR will be displayed in place of the truncated portion of any string. .RE .PD .PP --- 591,620 ---- True if at least \fIn\fP shell constructs were started. .RE .TP + .B %<\fIstring\fB<\fP + .TP + .B %>\fIstring\fB>\fP + .TP .B %[x\fIstring\fB]\fP ! Specifies truncation behaviour. ! The third form is equivalent to `%\fIxstringx\fP', ! i.e. \fIx\fP may be `<' or `>'. ! The numeric argument, which in the third form may appear immediately ! after the `[', specifies the maximum permitted length of the various strings that can be displayed in the prompt. If this integer is zero, or missing, truncation is disabled. Truncation is ! initially disabled. ! The forms with `<' truncate at the left of the string, ! and the forms with `>' truncate at the right of the string. ! For example, if the current directory is `/home/pike', ! the prompt `%8<..<%/' will expand to `..e/pike'. ! The \fIstring\fR will be displayed in place of the truncated portion of any string. + In this string, the terminating character (`<', `>' or `]'), + or in fact any character, may be quoted by a preceding `\e'. + % sequences are \fInot\fP treated specially. + If the \fIstring\fP is longer than the specified truncation length, + it will appear in full, completely replacing the truncated string. .RE .PD .PP -----BEGIN PGP SIGNATURE----- Version: 2.6.i iQBVAgUBMBLj+GWJ8JfKi+e9AQEhFQH+NXjxOpJvIxCfTIVJpPbhz/5Z0HcJqnWX H6rYZ/CY8mBtjmUU2vUdyMSvxEYZe1fIKajMixig0QTBi2qj1cR4vw== =1Rt2 -----END PGP SIGNATURE-----