From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 12492 invoked by alias); 11 Feb 2014 07:37:27 -0000 Mailing-List: contact zsh-workers-help@zsh.org; run by ezmlm Precedence: bulk X-No-Archive: yes List-Id: Zsh Workers List List-Post: List-Help: X-Seq: 32377 Received: (qmail 24329 invoked from network); 11 Feb 2014 07:37:21 -0000 X-Spam-Checker-Version: SpamAssassin 3.3.2 (2011-06-06) on f.primenet.com.au X-Spam-Level: X-Spam-Status: No, score=-1.9 required=5.0 tests=BAYES_00,RCVD_IN_DNSWL_NONE autolearn=ham version=3.3.2 From: Bart Schaefer Message-id: <140210233703.ZM11806@torch.brasslantern.com> Date: Mon, 10 Feb 2014 23:37:03 -0800 In-reply-to: <17919.1391985011@quattro> Comments: In reply to Oliver Kiddle "Re: Commit 137b15a fails X02zlevi test" (Feb 9, 11:30pm) References: <140208121311.ZM14905@torch.brasslantern.com> <140208144555.ZM16333@torch.brasslantern.com> <140209105343.ZM24252@torch.brasslantern.com> <17919.1391985011@quattro> X-Mailer: OpenZMail Classic (0.9.2 24April2005) To: zsh-workers@zsh.org Subject: Re: Commit 137b15a fails X02zlevi test MIME-version: 1.0 Content-type: text/plain; charset=us-ascii On Feb 9, 11:30pm, Oliver Kiddle wrote: } Subject: Re: Commit 137b15a fails X02zlevi test } } Bart wrote: } > I've been repeatedly running } > } > make check TESTNUM=X02 } > } > and have decided that it fails nondeterministically. } } On my desktop it never seems to fail. I just tried on my NAS box and } it appears to reliably fail there. After some futher fooling around ... I created this function: zpty_flush() { local junk if zpty -r -t zsh junk \*; then print -n -u $ZTST_fd "$*: ${(V)junk}" while zpty -r -t zsh junk \* do print -n -u $ZTST_fd "${(V)junk}"; done print -u $ZTST_fd '' fi } and then added calls to that in comptesteval, comptest, and zletest. For Y02completion, the output looks like this, repeated once per test with no blank lines: ------------ After comptesteval: ^[[K After comptest: ^[[K ------------ For X02zlevi, the output is unpredictable, but usually looks like this: ------------ Before zletest: ^[[K After zletest: end^[[K^M^M Before zletest: ^[[1m^[[7m%^[[m^[[1m^[[0m ^M ^M Before comptesteval: text^[[K^M^M text^[[K^H^M^M After comptesteval: ^[[K.^H. /tmp/comptest Before zletest: .27823^M^M After zletest: after^[[K^M^M after^[[K^H^M^M ------------ The blank lines are really there, I did not add them for readability. My conclusion is that being in viins mode causes ZLE to do much more work updating the display, resulting in some words being overstruck, extra cursor motions, etc. Combine this with using "print -lr" to try to send cursor position, etc., in-band at the end of each test, and confusion results. Now, why this would *sometimes* not happen is quite the mystery -- I would have thought that e.g. the "stty 38400" thrown in there would make it behave at least consistently, but no. The one that reads After comptesteval: ^[[K.^H. /tmp/comptest Before zletest: .27823^M^M is quite interesting, because it indicates that the prompt is being redrawn in the midst of the string ". /tmp/comptest.27823" which is written to the pty by comptesteval and expected to be executed as a command. I think that has to do with using \C-M as the binding for zle-finish. The following reformulation works more than 90% of the time for me, but still fails occasionally, and still not always on the same test. If I remove "zle -I", it becomes less reliable. If I remove "zle redisplay" it fails every time. If I change the zle-finish binding back to ^M it fails every time. Calling zpty_flush in comptest is not really needed ... by I don't know why it's not needed there, which bothers me. diff --git a/Test/comptest b/Test/comptest index f1c5af0..4a23e89 100644 --- a/Test/comptest +++ b/Test/comptest @@ -69,12 +69,15 @@ comp-finish () { zle -R } zle-finish () { - print -lr "" "BUFFER: $BUFFER" "CURSOR: $CURSOR" - (( region_active )) && print -lr "MARK: $MARK" - zle -K main + local buffer="$BUFFER" cursor="$CURSOR" mark="$MARK" + (( region_active)) || unset mark + BUFFER="" + zle -I zle clear-screen - zle send-break - zle -R + zle redisplay + print -lr "" "BUFFER: $buffer" "CURSOR: $cursor" + (( $+mark )) && print -lr "MARK: $mark" + zle accept-line } zle -N expand-or-complete-with-report zle -N list-choices-with-report @@ -83,30 +86,45 @@ zle -N zle-finish bindkey "^I" expand-or-complete-with-report bindkey "^D" list-choices-with-report bindkey "^Z" comp-finish -bindkey "^M" zle-finish -bindkey -a "^M" zle-finish +bindkey "^X" zle-finish +bindkey -a "^X" zle-finish ' } +zpty_flush() { + local junk + if zpty -r -t zsh junk \*; then + (( ZTST_verbose > 2 )) && print -n -u $ZTST_fd "$*: ${(V)junk}" + while zpty -r -t zsh junk \* ; do + (( ZTST_verbose > 2 )) && print -n -u $ZTST_fd "${(V)junk}" + done + (( ZTST_verobse > 2 )) && print -u $ZTST_fd '' + fi +} + comptesteval () { local tmp=/tmp/comptest.$$ print -lr - "$@" > $tmp + zpty_flush Before comptesteval zpty -w zsh ". $tmp" zpty -r -m zsh log_eval "**" || { print "prompt hasn't appeared." return 1 } + zpty_flush After comptesteval rm $tmp } comptest () { input="$*" + zpty_flush Before comptest zpty -n -w zsh "$input"$'\C-Z' zpty -r -m zsh log "***" || { print "failed to invoke finish widget." return 1 } + zpty_flush After comptest logs=(${(s::)log}) shift logs @@ -136,10 +154,12 @@ comptest () { zletest () { input="$*" - zpty -n -w zsh "$input"$'\C-M' + zpty_flush Before zletest + zpty -n -w zsh "$input"$'\C-X' zpty -r -m zsh log "***" || { print "failed to invoke finish widget." return 1 } + zpty_flush After zletest print -lr "${(@)${(ps:\r\n:)log##*}[1,-2]}" }