Zsh Mailing List Archive
Messages sorted by: Reverse Date, Date, Thread, Author

More prompt code changes



-----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-----



Messages sorted by: Reverse Date, Date, Thread, Author