From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 22940 invoked by alias); 9 Oct 2012 14:35:07 -0000 Mailing-List: contact zsh-users-help@zsh.org; run by ezmlm Precedence: bulk X-No-Archive: yes List-Id: Zsh Users List List-Post: List-Help: X-Seq: 17314 Received: (qmail 27946 invoked from network); 9 Oct 2012 14:35:04 -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.6 required=5.0 tests=BAYES_00,RCVD_IN_DNSWL_LOW autolearn=ham version=3.3.2 Received-SPF: neutral (ns1.primenet.com.au: 209.85.214.171 is neither permitted nor denied by SPF record at ntlworld.com) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20120113; h=mime-version:x-originating-ip:in-reply-to:references:date :message-id:subject:from:to:content-type:x-gm-message-state; bh=l0OKfWCXlGmuz6JfM/quQYrbWDxgQ5N++oTfMiESAR8=; b=jlToqaTevTgebiutOtZ9OTovUW5nQ3D4aJzi2YC6+zHschghUrkTJIPjSZ4osA8xDu HRf6N7cJlDUs7lcv7vuHZWODScpvvizGwglrqmSvc5pcFH4pD3Exd3v+6v35z1TFU9nm yKiAVAVCJ5SR1CBwcc95DGeeCJYfTuEEGcwv45v0a5eGtOQHXOrdI6w2Sd70/+5dW8YL Mhk+CzhHor5rSysQBnjt632dUWU4s6LEgXBxOyda3E1HAl0XHBxjB8H5Pvw564oFSS8S OhOQe+t9k1+y/dj+FOzBHElwJWfk1x+VLqCcWF2xekzL48a7l+fpYqAe8RS3TDr5dUcC nRyw== MIME-Version: 1.0 X-Originating-IP: [80.239.194.50] In-Reply-To: References: Date: Tue, 9 Oct 2012 15:34:58 +0100 Message-ID: Subject: Re: bug in replace-string: widget loses characters From: Peter Stephenson To: zsh-users@zsh.org Content-Type: text/plain; charset=ISO-8859-1 X-Gm-Message-State: ALoCoQluya7NKZecPASwGVN7lUy8wfpXxTFCeEItT6lOutNST9bx/UTrNa6KWAkZRcJU5FqNfR78 On 9 October 2012 12:22, Peter Stephenson wrote: > I think it's a problem with "undo". After the function has read the > original and replacement strings from the area under the command line, > it's supposed to undo all that, so that you don't see it as part of the > normal undo history (undo should take you back through the replacement, > then immediately back through any changes you made before invoking the > replace widget). It looks like that undo can go one change too far, > which means I've got the counting of undo changes wrong somewhere. > > I didn't really properly get to grips with the undo system, > so this isn't that surprising. I suppose it's no use hoping > anybody else is going to understand it. I'll take a look > later. I think this fix should be robust. It increments the undo change number at the point where we pass it as the value of the variable. This looks like a cop out, but it does absolutely guarantee the separation of changes before and after that point regardless of where the wires were attached to the fence posts. The zlong range should be big enough to cope. The one side effect is that $UNDO_CHANGE_NO is different each time it's read. I could fix that if anyone cared, but if it helped you could sort of look on it as a feature: you are guaranteed that all recorded change points are unique and monotonically increasing whether or not the line itself was changed. Index: Src/Zle/zle_utils.c =================================================================== RCS file: /cvsroot/zsh/zsh/Src/Zle/zle_utils.c,v retrieving revision 1.63 diff -p -u -r1.63 zle_utils.c --- Src/Zle/zle_utils.c 29 Mar 2012 20:31:33 -0000 1.63 +++ Src/Zle/zle_utils.c 9 Oct 2012 14:24:35 -0000 @@ -1520,23 +1520,25 @@ setlastline(void) int undo(char **args) { - zlong last_change = (zlong)0; + zlong last_change; if (*args) - { last_change = zstrtol(*args, NULL, 0); - } + else + last_change = (zlong)-1; handleundo(); do { - if(!curchange->prev) + struct change *prev = curchange->prev; + if(!prev) return 1; - if (unapplychange(curchange->prev)) - curchange = curchange->prev; + if (prev->changeno < last_change) + break; + if (unapplychange(prev)) + curchange = prev; else break; - } while (*args ? curchange->changeno != last_change : - (curchange->flags & CH_PREV)); + } while (last_change >= (zlong)0 || (curchange->flags & CH_PREV)); setlastline(); return 0; } @@ -1660,6 +1662,11 @@ zlecallhook(char *name, char *arg) zlong get_undo_current_change(UNUSED(Param pm)) { - return undo_changeno; + /* + * Increment the number in case a change is in progress; + * we don't want to back off what's already been done when + * we return to this change number. This eliminates any + * problem about the point where a change is numbered. + */ + return ++undo_changeno; } - pws