zsh-workers
 help / color / mirror / code / Atom feed
From: Bart Schaefer <schaefer@brasslantern.com>
To: zsh-workers@zsh.org
Subject: Re: Simulating ZLE_RPROMPT_INDENT=0
Date: Wed, 18 Dec 2013 23:33:25 -0800	[thread overview]
Message-ID: <131218233325.ZM4046@torch.brasslantern.com> (raw)
In-Reply-To: <131218104353.ZM23017@torch.brasslantern.com>
In-Reply-To: <20131218193711.68390493@pws-pc.ntlworld.com>

On Dec 18,  7:37pm, Peter Stephenson wrote:
}
} No, I mean have a builtin with an explicit test that tells the user if
} the terminal supports the feature or not.  Then changing the terminal
} and deciding whether to set a zero right-prompt indent can be done
} entirely in shell code.
} 
} TERM=mymmodernpowerfulterminalemulator
} if builtin-decides-the-terminal-supports-non-destructive-move-left
}   ZLE_RPROMPT_INDENT=0
} else
}   ZLE_RPROMPT_INDENT=1
} fi

As predicted I have not attempted to implement this builtin, but the
test it would need is for more than non-destructive-move-left.  In the
course of fiddling with moveto() I looked more closely at the "YE"
(termcap) / "sam" (terminfo) capability, which might give us enough
information.

However, if the builtin is able to give an accurate result, then we
could just do the test internally and set the offset ourselves.

Anwway, there are probably other places in the code that could benefit
from knowing about YE/sam, so I've captured it in another global that
goes with hasam and hasxn.  I also included code that makes use of
that to initialize rprompt_indent, but wrapped it in "#if 0" so as
not to change that behavior until after 5.0.4, because I'm sure it's
going to need some field testing.

ASIDE:  While testing, I tried setting TERM to various values that do
not have very many capabilities, such as "dumb".  I discovered the the
regular PS1 prompt will always, eventually, get erased and not redrawn
if scrolling back through the history with such a terminal.  The buffer
is still in the correct place, just the prompt is gone.  This behavior
is neither caused nor affected by the patch below.

ASIDE #2:  Having introduced IPDEF5U(), I wonder if there aren't some
of the other special variables that should have the PM_UNSET flag by
default.  OPTIND, OPTARG, and TRY_BLOCK_ERROR come to mind.

Working on moveto(), I discovered that backspace *is* the non-destructive
move-left in e.g. xterm, so I limited the test to tccan(TCLEFT).  Most
of the rest of that hunk is just a change in indentation.


diff --git a/Doc/Zsh/params.yo b/Doc/Zsh/params.yo
index 37c79b2..935fd5d 100644
--- a/Doc/Zsh/params.yo
+++ b/Doc/Zsh/params.yo
@@ -1548,7 +1548,7 @@ ifzman(zmanref(zshcompsys))\
 ifnzman(noderef(Completion System)).
 )
 vindex(ZLE_RPROMPT_INDENT)
-item(tt(ZLE_RPROMPT_INDENT))(
+item(tt(ZLE_RPROMPT_INDENT <S>))(
 If set, used to give the indentation between the right hand side of
 the right prompt in the line editor as given by tt(RPS1) or tt(RPROMPT)
 and the right hand side of the screen.  If not set, the value 1 is used.
diff --git a/Src/Zle/zle_refresh.c b/Src/Zle/zle_refresh.c
index debb973..fd54857 100644
--- a/Src/Zle/zle_refresh.c
+++ b/Src/Zle/zle_refresh.c
@@ -977,7 +977,7 @@ zrefresh(void)
     int tmpalloced;		/* flag to free tmpline when finished	     */
     int remetafy;		/* flag that zle line is metafied	     */
     int txtchange;		/* attributes set after prompts              */
-    int rprompt_off = 1;	/* Offset of rprompt from right of screen    */
+    int rprompt_off;		/* Offset of rprompt from right of screen    */
     struct rparams rpms;
 #ifdef MULTIBYTE_SUPPORT
     int width;			/* width of wide character		     */
@@ -1579,16 +1579,12 @@ zrefresh(void)
 		!strchr(rpromptbuf, '\t');
 	    if (put_rpmpt)
 	    {
-		struct value vbuf;
-		char *name = "ZLE_RPROMPT_INDENT";
-		if (getvalue(&vbuf, &name, 1)) {
-		    rprompt_off = (int)getintvalue(&vbuf);
-		    /* sanity to avoid horrible things happening */
-		    if (rprompt_off < 0)
-			rprompt_off = 0;
-		}
-		put_rpmpt =
-		    (int)ZR_strlen(nbuf[0]) + rpromptw < winw - rprompt_off;
+	      rprompt_off = rprompt_indent;
+	      /* sanity to avoid horrible things happening */
+	      if (rprompt_off < 0)
+		rprompt_off = 0;
+	      put_rpmpt =
+		(int)ZR_strlen(nbuf[0]) + rpromptw < winw - rprompt_off;
 	    }
 	}
     } else {
@@ -2127,19 +2123,24 @@ moveto(int ln, int cl)
     const REFRESH_ELEMENT *rep;
 
     if (vcs == winw) {
-	vln++, vcs = 0;
-	if (!hasam) {
-	    zputc(&zr_cr);
-	    zputc(&zr_nl);
+	if (rprompt_indent == 0 && tccan(TCLEFT)) {
+	  tc_leftcurs(1);
+	  vcs--;
 	} else {
-	    if ((vln < nlnct) && nbuf[vln] && nbuf[vln]->chr)
-		rep = nbuf[vln];
-	    else
-		rep = &zr_sp;
-	    zputc(rep);
-	    zputc(&zr_cr);
-	    if ((vln < olnct) && obuf[vln] && obuf[vln]->chr)
-		*obuf[vln] = *rep;
+	    vln++, vcs = 0;
+	    if (!hasam) {
+		zputc(&zr_cr);
+		zputc(&zr_nl);
+	    } else {
+		if ((vln < nlnct) && nbuf[vln] && nbuf[vln]->chr)
+		    rep = nbuf[vln];
+		else
+		    rep = &zr_sp;
+		zputc(rep);
+		zputc(&zr_cr);
+		if ((vln < olnct) && obuf[vln] && obuf[vln]->chr)
+		    *obuf[vln] = *rep;
+	    }
 	}
     }
 
diff --git a/Src/init.c b/Src/init.c
index 53c4fbd..f5aae71 100644
--- a/Src/init.c
+++ b/Src/init.c
@@ -77,7 +77,7 @@ mod_export int tclen[TC_COUNT];
 /**/
 int tclines, tccolumns;
 /**/
-mod_export int hasam, hasxn;
+mod_export int hasam, hasxn, hasye;
 
 /* Value of the Co (max_colors) entry: may not be set */
 
@@ -699,6 +699,7 @@ init_term(void)
 	/* check whether terminal has automargin (wraparound) capability */
 	hasam = tgetflag("am");
 	hasxn = tgetflag("xn"); /* also check for newline wraparound glitch */
+	hasye = tgetflag("YE"); /* print in last column does carriage return */
 
 	tclines = tgetnum("li");
 	tccolumns = tgetnum("co");
@@ -748,6 +749,9 @@ init_term(void)
 	    tcstr[TCCLEARSCREEN] = ztrdup("\14");
 	    tclen[TCCLEARSCREEN] = 1;
 	}
+#if 0	/* This might work, but there may be more to it */
+	rprompt_indent = (hasye || !tccan(TCLEFT)) ? 1 : 0;
+#endif
     }
     return 1;
 }
@@ -999,6 +1003,15 @@ setupvals(void)
     setiparam("COLUMNS", zterm_columns);
     setiparam("LINES", zterm_lines);
 #endif
+    {
+	/* Import from environment, overrides init_term() */
+	struct value vbuf;
+	char *name = "ZLE_RPROMPT_INDENT";
+	if (getvalue(&vbuf, &name, 1) && !(vbuf.flags & PM_UNSET))
+	    rprompt_indent = getintvalue(&vbuf);
+	else
+	    rprompt_indent = 1;
+    }
 
 #ifdef HAVE_GETRLIMIT
     for (i = 0; i != RLIM_NLIMITS; i++) {
diff --git a/Src/params.c b/Src/params.c
index d6711e4..26ad6b2 100644
--- a/Src/params.c
+++ b/Src/params.c
@@ -97,6 +97,7 @@ zlong lastval,		/* $?           */
      lastpid,		/* $!           */
      zterm_columns,	/* $COLUMNS     */
      zterm_lines,	/* $LINES       */
+     rprompt_indent,	/* $ZLE_RPROMPT_INDENT */
      ppid,		/* $PPID        */
      zsh_subshell;	/* $ZSH_SUBSHELL */
 /**/
@@ -316,8 +317,10 @@ IPDEF4("PPID", &ppid),
 IPDEF4("ZSH_SUBSHELL", &zsh_subshell),
 
 #define IPDEF5(A,B,F) {{NULL,A,PM_INTEGER|PM_SPECIAL},BR((void *)B),GSU(F),10,0,NULL,NULL,NULL,0}
+#define IPDEF5U(A,B,F) {{NULL,A,PM_INTEGER|PM_SPECIAL|PM_UNSET},BR((void *)B),GSU(F),10,0,NULL,NULL,NULL,0}
 IPDEF5("COLUMNS", &zterm_columns, zlevar_gsu),
 IPDEF5("LINES", &zterm_lines, zlevar_gsu),
+IPDEF5U("ZLE_RPROMPT_INDENT", &rprompt_indent, zlevar_gsu),
 IPDEF5("OPTIND", &zoptind, varinteger_gsu),
 IPDEF5("SHLVL", &shlvl, varinteger_gsu),
 IPDEF5("TRY_BLOCK_ERROR", &try_errflag, varinteger_gsu),


  reply	other threads:[~2013-12-19  7:33 UTC|newest]

Thread overview: 10+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2013-12-18  6:43 Bart Schaefer
2013-12-18  9:27 ` Peter Stephenson
2013-12-18 17:26   ` Bart Schaefer
2013-12-18 17:38     ` Peter Stephenson
2013-12-18 18:43       ` Bart Schaefer
2013-12-18 19:37         ` Peter Stephenson
2013-12-19  7:33           ` Bart Schaefer [this message]
2013-12-19  8:04             ` Bart Schaefer
2013-12-19 20:36             ` Peter Stephenson
2013-12-20  7:28               ` IPDEF5U [was Re: Simulating ZLE_RPROMPT_INDENT=0] Bart Schaefer

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=131218233325.ZM4046@torch.brasslantern.com \
    --to=schaefer@brasslantern.com \
    --cc=zsh-workers@zsh.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
Code repositories for project(s) associated with this public inbox

	https://git.vuxu.org/mirror/zsh/

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).