From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 17785 invoked by alias); 6 Dec 2014 00:52:56 -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: 33880 Received: (qmail 15757 invoked from network); 6 Dec 2014 00:52:45 -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=-2.7 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,FREEMAIL_FROM,RCVD_IN_DNSWL_LOW autolearn=ham version=3.3.2 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=mime-version:in-reply-to:references:date:message-id:subject:from:to :cc:content-type; bh=96KrrjATPAnN+aOe28t5nCx0CMURYWQ2BHi5CNY2Ix8=; b=uwRMCS51aBH8XoPK2cnRfkYbvDrgu7vqaTGeSbbz5itaBUK8/S7ljySNd+c2Y/VSL9 5cG5bQIi9mv9dxRuZEi986c+ghe4MNEGNfHkMKISW3lUzmLrySMNmhVaqiLRg3ifVg4v aNLBCtTOuXDeOEGF/1gAuaOqq2dDjYctLi0cJzrq+pBZgVqX77x7LtQwaTImmDBsTIq/ KWE/7r/QHmwF7EpPzqlHBpYL6zYEnDy+bQNV9aMnqT+NLe8X1pxRD4dvn0PX78flYRLV W/pRKrOnZ7RTws+YySSYYjhXaAItUqB1rFPlngSXt7VH4VyxP8X2hd84i6xRJBVYTWA1 6MkA== MIME-Version: 1.0 X-Received: by 10.107.130.197 with SMTP id m66mr1454238ioi.10.1417827163445; Fri, 05 Dec 2014 16:52:43 -0800 (PST) In-Reply-To: References: <20141202155452.647182b4@pwslap01u.europe.root.pri> <141202084858.ZM31517@torch.brasslantern.com> <20141202172654.30e7d380@pwslap01u.europe.root.pri> <141204085606.ZM9146@torch.brasslantern.com> <20141204171226.301e9d2c@pwslap01u.europe.root.pri> <141205002023.ZM19736@torch.brasslantern.com> <20141205145054.655a2f70@pwslap01u.europe.root.pri> <141205100632.ZM508@torch.brasslantern.com> <20141205181330.2b458b46@pwslap01u.europe.root.pri> <20141205203417.2bc66b7b@pws-pc.ntlworld.com> <20141205220717.2f86bdd2@pws-pc.ntlworld.com> Date: Sat, 6 Dec 2014 01:52:43 +0100 Message-ID: Subject: Re: Interrupting globs (Re: Something rotten in tar completion) From: Mikael Magnusson To: Peter Stephenson Cc: "Zsh Hackers' List" Content-Type: text/plain; charset=UTF-8 On Sat, Dec 6, 2014 at 1:36 AM, Mikael Magnusson wrote: > On Fri, Dec 5, 2014 at 11:07 PM, Peter Stephenson > wrote: >> On Fri, 5 Dec 2014 20:34:17 +0000 >> Peter Stephenson wrote: >>> On the other problem I came up with, that eval is resetting errflag even >>> if you've interrupted: how about the following? Add a bit to errflag to >>> signify that the user interrupted the shell rather than that some >>> internal error (e.g. syntax) occurred. Only reset this new bit in a few >>> key places: the main command loop when executing, the top of ZLE when >>> editing being the obvious places. Convert other "errflag = 0" >>> assignments case by case so that they just remove bit 0; then eval can >>> continue to do its job of acting as a sandbox but without screwing up >>> the behaviour of interrupts. I think doing that is fairly mechanical >>> and it achieves what's needed without compromising anything else. >> >> Here's my first go; it does seem to do what I want, and as a by-product >> fixes all the little race conditions we've always had that meant you >> couldn't interrupt chunks of code that were executed in any kind of >> sandbox because the condition got reset afterwards. I think a few of >> these have been annoying me over the years. >> >> The general strategy is to use the bit ERRFLAG_ERROR for internal >> failures and ERRFLAG_INT for user interrupts. There are only two >> cases of the latter: on an untrapped SIGINT, the obvious case, and also >> on a trapped SIGINT or SIGQUIT where we've been told to behave as if the >> trap didn't trap the error condition. That's straightforward for >> SIGINT, less so for SIGQUIT but I took my cue from the fact that Bart >> thought it worthwhile trapping SIGQUIT as an interactive "no, I really >> mean abort" in completion, which implies that if we trap it we want it >> to work at least as well as SIGINT. >> >> Correspondingly, most of the time only the ERRFLAG_ERROR bit gets >> reset. ERRFLAG_INT gets reset only in the following cases: >> >> - in the main command loop. This is what causes the shell not to exit but >> instead go back to the main command loop when you ^C a command. >> >> - at the start of zleread, so we can read the next thing to do whatever >> just happened. I'm not sure this is particularly useful since >> in this case you'd typically expect the previous condition to have >> occurred and it could mean e.g. you ignore an interrupt that >> occurred just before a "vared". >> >> - when we just finished completion. This is needed so that the cases >> that got this whole business kicked off behave as now (but more >> reliably) --- a ^C gets you back to the command line, but the command >> line is not trashed as it would be if you ^Ced outside completion (try >> it if you're confused). There's a race here, but it's no worse than it >> ever was. >> >> To ensure ERRFLAG_INT doesn't get reset unnecessarily there are a number >> of cases where restoring errflag to a previously saved value keeps the >> ERRFLAG_INT bit if it got set in the meanwhile. I hope the rationale >> here is obvious --- the ERRFLAG_ERROR is an internal state that needs >> resetting, the ERRFLAG_INT an asynchronous condition where the user >> doesn't care what the internal state is. >> >> By the way, looking at the patch below you might wonder if it wouldn't >> be more efficient to add a separate flag for interrupt error conditions >> to test. It wouldn't --- there are many more cases where errflag is >> tested than when it is set, not affected by the patch below. >> >> I suspect we'll just have to try this out and see how it works. > > This seems to work well for me in the cases you talked about, but I > quickly noticed one surprising problem. I have some stuff in my > chpwd() hook to show git branches and stuff, and these used to be > interruptible by ctrl-c (the commands are very fast with hot cache, > but can be somewhat painful with cold cache, like 5-10 seconds delay). > With the patch, I cannot interrupt them (sometimes?). > > chpwd () { > stty -echo >&/dev/null > test -f .tdldb && tdll -1 >&2 > test -d .git && { > git branch > test -d .git/svn && { > echo -n r > git svn find-rev master > } > git name-rev HEAD > git describe --tags HEAD 2> /dev/null > } >&2 > if [[ "$_NONOCDLS" = 1 ]] > then > ls $LS_OPTIONS >&2 > fi > } Ah, I think I understand what's happening now. Prior to the patch, pressing ctrl-c would abort out of chpwd() completely, but now it just aborts whichever single command is running. Since I have three git commands in there, I now need to press ctrl-c three times to get back to the prompt quickly. (I would like it to only require one). -- Mikael Magnusson