From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 7237 invoked from network); 14 Jul 2005 18:25:25 -0000 Received: from news.dotsrc.org (HELO a.mx.sunsite.dk) (130.225.247.88) by ns1.primenet.com.au with SMTP; 14 Jul 2005 18:25:25 -0000 Received: (qmail 25712 invoked from network); 14 Jul 2005 18:25:19 -0000 Received: from sunsite.dk (130.225.247.90) by a.mx.sunsite.dk with SMTP; 14 Jul 2005 18:25:19 -0000 Received: (qmail 6296 invoked by alias); 14 Jul 2005 18:25:16 -0000 Mailing-List: contact zsh-workers-help@sunsite.dk; run by ezmlm Precedence: bulk X-No-Archive: yes X-Seq: 21464 Received: (qmail 6287 invoked from network); 14 Jul 2005 18:25:16 -0000 Received: from news.dotsrc.org (HELO a.mx.sunsite.dk) (130.225.247.88) by sunsite.dk with SMTP; 14 Jul 2005 18:25:16 -0000 Received: (qmail 25400 invoked from network); 14 Jul 2005 18:25:16 -0000 Received: from dsl3-63-249-88-2.cruzio.com (HELO dot.blorf.net) (63.249.88.2) by a.mx.sunsite.dk with SMTP; 14 Jul 2005 18:25:10 -0000 Received: by dot.blorf.net (Postfix, from userid 1000) id 7B6D2CBC4; Thu, 14 Jul 2005 11:25:06 -0700 (PDT) Date: Thu, 14 Jul 2005 11:25:06 -0700 From: Wayne Davison To: zsh-workers@sunsite.dk Subject: PATCH: PROMPT_SP Message-ID: <20050714182506.GB11296@blorf.net> Mime-Version: 1.0 Content-Type: multipart/mixed; boundary="sm4nu43k4a2Rpi4c" Content-Disposition: inline User-Agent: Mutt/1.5.9i X-Spam-Checker-Version: SpamAssassin 3.0.2 on a.mx.sunsite.dk X-Spam-Level: X-Spam-Status: No, score=-2.3 required=6.0 tests=AWL,BAYES_00,SUBJ_ALL_CAPS autolearn=no version=3.0.2 X-Spam-Hits: -2.3 --sm4nu43k4a2Rpi4c Content-Type: text/plain; charset=us-ascii Content-Disposition: inline I've been doing some work on this new option I'm suggesting. The current name I'm leaning towards is PROMPT_SP, so that's what this patch implements. Please feel free to comment about this or suggest a better name. The patch was also changed to try to output fewer characters, and also to try to prevent mouse selection from joining a partial line with the prompt line that follows it (resulting in a lot of spaces being copied to the clipboard). So, this patch uses TCMULTRIGHT or TCRIGHT (when available) to get to (or near) the right margin, outputs 2 spaces (which might induce a wrap), and then (if save- and restore-cursor are there), it outputs two backspaces and either tries to clear-to-EOL or to delete a character before restoring the cursor position. In my testing, as long as the cursor ends up on the previous line by the backspaces, both xterm and konsole fix the selection problem using either clear-to-EOL or delete-char. However, the only way I currently know of to enable a wrappable left margin is to run zsh under screen, so suggestions are welcomed as to how to enable a soft left margin in a modern day terminal emulator. One thing I added while I was adding support for looking up the save- and restore-cursor escapes was a lookup for the backspace character ("bc" is only supposed to be set if the "bs" flag is not set, but I just made the code always look up "bc" and default the value to "\b" if it wasn't found). Since some other parts of zsh use literal \b characters, this might be overkill and it is debatable if we really need it. This patch is based on the CVS version, not my prior patch. ..wayne.. --sm4nu43k4a2Rpi4c Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename="prompt_sp.patch" --- Doc/Zsh/options.yo 18 Mar 2005 22:40:17 -0000 1.37 +++ Doc/Zsh/options.yo 14 Jul 2005 17:49:54 -0000 @@ -906,6 +906,15 @@ Print a carriage return just before prin a prompt in the line editor. This is on by default as multi-line editing is only possible if the editor knows where the start of the line appears. ) +pindex(PROMPT_SP) +cindex(prompt, save partial lines) +item(tt(PROMPT_SP) (tt(PLUS()V)) )( +Attempt to preserve any partially-output line (i.e. a line that did not end +with a newline) by outputting a series of spaces prior to the carriage return +that is output by PROMPT_CR. This only works if your terminal has automatic +margins. Also, if the PROMPT_CR option is not set, enabling this option will +have no effect. This option is on by default. +) pindex(PROMPT_PERCENT) cindex(prompt, % expansion) item(tt(PROMPT_PERCENT) )( --- Src/init.c 13 Jun 2005 14:59:37 -0000 1.53 +++ Src/init.c 14 Jul 2005 17:49:55 -0000 @@ -77,7 +77,7 @@ mod_export int tclen[TC_COUNT]; /**/ int tclines, tccolumns; /**/ -mod_export int hasam; +mod_export int hasam, hasxn; /* Pointer to read-key function from zle */ @@ -518,7 +518,7 @@ static char *tccapnams[TC_COUNT] = { "cl", "le", "LE", "nd", "RI", "up", "UP", "do", "DO", "dc", "DC", "ic", "IC", "cd", "ce", "al", "dl", "ta", "md", "so", "us", "me", "se", "ue", "ch", - "ku", "kd", "kl", "kr" + "ku", "kd", "kl", "kr", "sc", "rc", "bc" }; /* Initialise termcap */ @@ -573,6 +573,7 @@ init_term(void) /* check whether terminal has automargin (wraparound) capability */ hasam = tgetflag("am"); + hasxn = tgetflag("xn"); /* also check for newline wraparound glitch */ tclines = tgetnum("li"); tccolumns = tgetnum("co"); @@ -587,10 +588,22 @@ init_term(void) termflags |= TERM_NOUP; } - /* if there's no termcap entry for cursor left, use \b. */ + /* most termcaps don't define "bc" because they use \b. */ + if (!tccan(TCBACKSPACE)) { + tcstr[TCBACKSPACE] = ztrdup("\b"); + tclen[TCBACKSPACE] = 1; + } + + /* if there's no termcap entry for cursor left, use backspace. */ if (!tccan(TCLEFT)) { - tcstr[TCLEFT] = ztrdup("\b"); - tclen[TCLEFT] = 1; + tcstr[TCLEFT] = tcstr[TCBACKSPACE]; + tclen[TCLEFT] = tclen[TCBACKSPACE]; + } + + if (tccan(TCSAVECURSOR) && !tccan(TCRESTRCURSOR)) { + tclen[TCSAVECURSOR] = 0; + zsfree(tcstr[TCSAVECURSOR]); + tcstr[TCSAVECURSOR] = NULL; } /* if the termcap entry for down is \n, don't use it. */ --- Src/options.c 18 Mar 2005 22:40:26 -0000 1.22 +++ Src/options.c 14 Jul 2005 17:49:55 -0000 @@ -181,6 +181,7 @@ static struct optname optns[] = { {NULL, "promptbang", OPT_KSH, PROMPTBANG}, {NULL, "promptcr", OPT_ALL, PROMPTCR}, {NULL, "promptpercent", OPT_NONBOURNE, PROMPTPERCENT}, +{NULL, "promptsp", OPT_ALL, PROMPTSP}, {NULL, "promptsubst", OPT_KSH, PROMPTSUBST}, {NULL, "pushdignoredups", OPT_EMULATE, PUSHDIGNOREDUPS}, {NULL, "pushdminus", OPT_EMULATE, PUSHDMINUS}, --- Src/zsh.h 1 Jun 2005 10:45:42 -0000 1.74 +++ Src/zsh.h 14 Jul 2005 17:49:55 -0000 @@ -1594,6 +1594,7 @@ enum { PROMPTBANG, PROMPTCR, PROMPTPERCENT, + PROMPTSP, PROMPTSUBST, PUSHDIGNOREDUPS, PUSHDMINUS, @@ -1716,7 +1717,10 @@ struct ttyinfo { #define TCDOWNCURSOR 26 #define TCLEFTCURSOR 27 #define TCRIGHTCURSOR 28 -#define TC_COUNT 29 +#define TCSAVECURSOR 29 +#define TCRESTRCURSOR 30 +#define TCBACKSPACE 31 +#define TC_COUNT 32 #define tccan(X) (tclen[X]) --- Src/Zle/zle_main.c 8 Apr 2005 16:58:21 -0000 1.68 +++ Src/Zle/zle_main.c 14 Jul 2005 17:49:56 -0000 @@ -962,8 +962,30 @@ zleread(char **lp, char **rp, int flags, } } initundo(); - if (isset(PROMPTCR)) + if (isset(PROMPTCR)) { + /* The PROMPT_SP heuristic will move the prompt down to a new line + * if there was any dangling output on the line (assuming the terminal + * has automatic margins, but we try even if hasam isn't set). */ + if (isset(PROMPTSP)) { + if (hasxn) /* w/o this, a delayed wrap might be lost by TCRIGHT */ + putc(' ', shout); + if (tccan(TCSAVECURSOR) + && tcmultout(TCRIGHT, TCMULTRIGHT, columns - 3)) { + putc(' ', shout); + putc(' ', shout); + tcout(TCSAVECURSOR); + tcout(TCBACKSPACE); + tcout(TCBACKSPACE); + if (tccan(TCCLEAREOL)) + tcout(TCCLEAREOL); + else + tcmultout(TCDEL, TCMULTDEL, 1); + tcout(TCRESTRCURSOR); + } else + fprintf(shout, "%*s", (int)columns - 1, ""); + } putc('\r', shout); + } if (tmout) alarm(tmout); zleactive = 1; --sm4nu43k4a2Rpi4c--