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

Re: 'zle redisplay' bug in 5.3?



On Sat, 7 Jan 2017 20:46:40 -0800
Bart Schaefer <schaefer@xxxxxxxxxxxxxxxx> wrote:
> On Jan 7,  8:04pm, Peter Stephenson wrote:
> } Subject: Re: 'zle redisplay' bug in 5.3?
> }
> } OK, how about this as an alternative to the previous change to the
> } refresh code?  If I'm following properly, this was a problem when
> } 
> } TRAPINT () {
> } 	zle reset-prompt
> } 	return 127
> } }
> } 
> } was in effect during interruption at a completion list.
> 
> That's correct.  However, this patch (checking errflag) does not fix
> the issue with interrupts.

There isn't a *the* issue, is there?  There can't be; the interrupt can
go off absolutely anywhere.  I've fixed the one with complist, which is
what was originally reported, now you're saying there's something else...

>     autoload compinit
>     compinit -u -D
>     TRAPINT () {
>       zle reset-prompt
>       return 127
>     }
>     _delay() { sleep 10 }
>     zstyle \* completer _complete _delay
> 
> Now complete after e.g. "ls " and press ^C within 10 seconds.  The
> complist module does not need to be involved, so a change only there
> does not help.

That is indeed a completely different problem, at least the problem that
shows up when I try this certainly is.  I'm not sure the _delay has got
much to do with it, though, so it's possible there's yet more.

We're not actually in or under completion code here --- though the hook
mechanism makes that statement less useful than it might otherwise be.
However, that does mean that in this case we're not aborting a display
--- we're aborting to a new command line.  (That's the same as if you
just do the straight compinit then the same key sequence, but the
modification of the completer means that you ought to look at the
internal state when the interrupt happens to confirm, which I've done.)
It turns out the prompt doesn't get redrawn on that line because
clearflag isn't initialised to zero, even though it's value is
meaningless when we restart ZLE for the new line as we should redraw
everything from scratch --- that's the residual effect of the completion
code's hook using dolastprompt, I think.

It looks like the line we're aborting isn't completely tidied up,
either, there's a bit of stray output from the reset-prompt, but I
consider that very minor as we're aborting it completely, and separate
again.

I intend to commit this.  Please we can take problems one at a time?

diff --git a/Src/Zle/complist.c b/Src/Zle/complist.c
index 2edaf6e..0350388 100644
--- a/Src/Zle/complist.c
+++ b/Src/Zle/complist.c
@@ -1993,7 +1993,8 @@ complistmatches(UNUSED(Hookdef dummy), Chdata dat)
     if (noselect > 0)
 	noselect = 0;
 
-    if ((minfo.asked == 2 && mselect < 0) || nlnct >= zterm_lines) {
+    if ((minfo.asked == 2 && mselect < 0) || nlnct >= zterm_lines ||
+	errflag) {
 	showinglist = 0;
 	amatches = oamatches;
 	return (noselect = 1);
diff --git a/Src/Zle/zle_main.c b/Src/Zle/zle_main.c
index 15ea796..6c271b5 100644
--- a/Src/Zle/zle_main.c
+++ b/Src/Zle/zle_main.c
@@ -1245,6 +1245,7 @@ zleread(char **lp, char **rp, int flags, int context, char *init, char *finish)
     resetneeded = 0;
     fetchttyinfo = 0;
     trashedzle = 0;
+    clearflag = 0;
     raw_lp = lp;
     lpromptbuf = promptexpand(lp ? *lp : NULL, 1, NULL, NULL, &pmpt_attr);
     raw_rp = rp;
diff --git a/Src/Zle/zle_refresh.c b/Src/Zle/zle_refresh.c
index 8d173cd..8391739 100644
--- a/Src/Zle/zle_refresh.c
+++ b/Src/Zle/zle_refresh.c
@@ -2434,8 +2434,8 @@ redisplay(UNUSED(char **args))
     moveto(0, 0);
     zputc(&zr_cr);		/* extra care */
     tc_upcurs(lprompth - 1);
-    resetneeded = !showinglist;
-    clearflag = showinglist;
+    resetneeded = 1;
+    clearflag = 0;
     return 0;
 }
 
diff --git a/Src/Zle/zle_thingy.c b/Src/Zle/zle_thingy.c
index c709285..c003148 100644
--- a/Src/Zle/zle_thingy.c
+++ b/Src/Zle/zle_thingy.c
@@ -703,7 +703,7 @@ bin_zle_call(char *name, char **args, UNUSED(Options ops), UNUSED(char func))
 {
     Thingy t;
     struct modifier modsave = zmod;
-    int ret, saveflag = 0, setbindk = 0;
+    int ret, saveflag = 0, setbindk = 0, remetafy;
     char *wname = *args++, *keymap_restore = NULL, *keymap_tmp;
 
     if (!wname)
@@ -714,7 +714,15 @@ bin_zle_call(char *name, char **args, UNUSED(Options ops), UNUSED(char func))
 	return 1;
     }
 
-    UNMETACHECK();
+    /*
+     * zle is callable in traps, so we can't be sure the line is
+     * in its normal state.
+     */
+    if (zlemetaline) {
+	unmetafy_line();
+	remetafy = 1;
+    } else
+	remetafy = 0;
 
     while (*args && **args == '-') {
 	char *num;
@@ -728,6 +736,8 @@ bin_zle_call(char *name, char **args, UNUSED(Options ops), UNUSED(char func))
 		num = args[0][1] ? args[0]+1 : args[1];
 		if (!num) {
 		    zwarnnam(name, "number expected after -%c", **args);
+		    if (remetafy)
+			metafy_line();
 		    return 1;
 		}
 		if (!args[0][1])
@@ -745,19 +755,26 @@ bin_zle_call(char *name, char **args, UNUSED(Options ops), UNUSED(char func))
 		keymap_tmp = args[0][1] ? args[0]+1 : args[1];
 		if (!keymap_tmp) {
 		    zwarnnam(name, "keymap expected after -%c", **args);
+		    if (remetafy)
+			metafy_line();
 		    return 1;
 		}
 		if (!args[0][1])
 		    *++args = "" - 1;
 		keymap_restore = dupstring(curkeymapname);
-		if (selectkeymap(keymap_tmp, 0))
+		if (selectkeymap(keymap_tmp, 0)) {
+		    if (remetafy)
+			metafy_line();
 		    return 1;
+		}
 		break;
 	    case 'w':
 		setbindk = 1;
 		break;
 	    default:
 		zwarnnam(name, "unknown option: %s", *args);
+		if (remetafy)
+		    metafy_line();
 		return 1;
 	    }
 	}
@@ -775,6 +792,8 @@ bin_zle_call(char *name, char **args, UNUSED(Options ops), UNUSED(char func))
 	zmod = modsave;
     if (keymap_restore)
 	selectkeymap(keymap_restore, 0);
+    if (remetafy)
+	metafy_line();
     return ret;
 }
 



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