From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 19384 invoked by alias); 24 Jul 2015 19:12:36 -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: 35886 Received: (qmail 27878 invoked from network); 24 Jul 2015 19:12:32 -0000 X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) 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,RCVD_IN_MSPIKE_H2 autolearn=ham autolearn_force=no version=3.4.0 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=yahoo.co.uk; s=s2048; t=1437764792; bh=3vCOI/+pRNAwCcYGm40PtL+ASN3898Ekna2w8J+DFeE=; h=In-reply-to:From:References:To:Subject:Date:From:Subject; b=kC5fpl4d3oT4+bR0cru+tmBCLnin/Bk9s8xMq7xpfacwg7i/BsRJvK1zArndtumLdo23UwoLk5Tn49tIQKNiBJUtxQsT3R9ngEb11A2x5R2U18yZDcUyUioFtdRWuVc7sTJn44RHH1OjZj/dJYjYUFZrMak6MorAP5HOM+6hVr7QH0eiVhVWEc4zN2R3StBJ5wJHBQewFlcKZTVSrgv0RIwIZTdHuvW//Fm7HZ1H1Yv4Qt7eHbqvWFJ5yKqoP0SVk9u/SCS4S+2Bw3SnWa5uSfkMtnbraVRgxORSeCtqCbeDrWuLxQG7+QmY+fFJvdNITnKDyQWXZOC34wwAQWpyjQ== X-Yahoo-Newman-Id: 163469.32522.bm@smtp149.mail.ir2.yahoo.com X-Yahoo-Newman-Property: ymail-3 X-YMail-OSG: ORNkrXwVM1nm1Le.gyvz.2csLwC3jQg6cArg9eFNKo2YDHG 4EKqG4QkHXa7S9tnf8GV36o_Z128QqarEHL_6Sz9qfzi3dcksEcKI5UakvPG O39owyD_EXO6EmY04.VKpiv.UgeEA9IaS96OhyybbpohR7JuPuDNhqwikRT7 HFvdy_xNf03U7yAh2dPSCLaInbJDDHAY6oNRuiWzz8jfgQxtughwZGo7rgLY rkOtYYOyMcql6Ko9xkCWMCVLnM.ylpzsyDW35s_0HGjspis7W1.NG7jUNb6R PNVHAZA7ysqHioerZgB_aRBP6KvHnmZssdBBYRgFmZBGiQtOgrvGPphoq2AJ DD343J1omSBWk8Ig3RbgBo2h8wAAIWdw4x7wkNhtRdKNOifhfvzWrhd8odp2 tt4f_VDQ7tCgylLf_Lm98nFQ5HGf2Qw.di5k1bt4swaZeyoppbJOl2B_d67V Aj_hX3K1lB0nqGhRaHCGGEeF7l9ucuILbdAP2gMfe.ug7hhR7Jkl1yM3.bLg .ptqJ1wsRj3DraiIUzGiexpj9TcH_MQ-- X-Yahoo-SMTP: opAkk_CswBAce_kJ3nIPlH80cJI- In-reply-to: <150723220642.ZM18235@torch.brasslantern.com> From: Oliver Kiddle References: <7277.1437023995@thecus.kiddle.eu> <150716131504.ZM18155@torch.brasslantern.com> <150718110859.ZM4405@torch.brasslantern.com> <19088.1437274234@thecus.kiddle.eu> <485.1437632598@thecus.kiddle.eu> <150723220642.ZM18235@torch.brasslantern.com> To: zsh workers Subject: Vim special marks - Re: PATCH: highlight pasted text MIME-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-ID: <9888.1437764790.1@thecus.kiddle.eu> Date: Fri, 24 Jul 2015 21:06:30 +0200 Message-ID: <9889.1437764790@thecus.kiddle.eu> Bart wrote: > } Apart from using a bindkey -s sequence that finishes with a widget that > } has ZLE_YANK set. > > It could be enabled by poking into region_highlight if the yankb / yanke > internal variables were exposed via zsh/zleparam. Vim has special marks for jumping to the start and end of the most recent change: `[ and `]. There's also `. which is similar. In effect, this is much the same as yankb and yanke after a paste. I think it'd be better to make something more general like that available. It's a feature I use quite a bit in vim. Is there anything in emacs like yankb/yanke? The following is an implementation that works by digging in the undo information. This has the advantage of keeping the code related to this feature contained within vigotomark rather than having to sprinkle code everywhere to update the special marks. There's one very unfortunate effect of this design choice, however: if the start of some inserted text looks the same as what was there before, the undo mechanism will identify the later characters as having been inserted rather than the earlier ones. Any ideas: stick with this and ignore that bug, hack in some way of hinting to undo where it should look for changes, add global variables that are updated everywhere or something else? Oliver diff --git a/Src/Zle/zle_move.c b/Src/Zle/zle_move.c index d751c43..1b6177b 100644 --- a/Src/Zle/zle_move.c +++ b/Src/Zle/zle_move.c @@ -876,24 +876,81 @@ int vigotomark(UNUSED(char **args)) { ZLE_INT_T ch; + int *markcs, *markhist = 0; int oldcs = zlecs; int oldline = histline; + struct change *current; + int tmpcs, tmphist, found = 0; ch = getfullchar(0); - if (ch == ZWC('\'') || ch == ZWC('`')) - ch = 26; - else { - if (ch < ZWC('a') || ch > ZWC('z')) + if (ch == ZWC('\'') || ch == ZWC('`')) { + markhist = vimarkline + 26; + markcs = vimarkcs + 26; + } else if (ch == ZWC('[')) { + current = curchange->prev; + tmpcs = zlell; + tmphist = histline; + /* find lowest change offset in current undo change */ + for (; current; current = current->prev) { + if (current->hist != tmphist && found) + break; + if (current->off < tmpcs || current->hist != tmphist) + tmpcs = current->off; + tmphist = current->hist; + if (!found && (current->insl || current->dell)) + found = 1; + if (!(current->flags & CH_PREV)) + break; + } + if (!found) return 1; - ch -= ZWC('a'); - } - if (!vimarkline[ch]) - return 1; - if (curhist != vimarkline[ch] && !zle_goto_hist(vimarkline[ch], 0, 0)) { - vimarkline[ch] = 0; + markcs = &tmpcs; + markhist = &tmphist; + } else if (ch == ZWC(']')) { + for (current = curchange->prev;current && current->flags & CH_PREV; + current = current->prev) {} + if (!current) + return 1; + tmpcs = current->off + current->insl; + tmphist = histline; + /* highest offset after insert in current undo change */ + for (;current != curchange;current = current->next) { + if (!found && (current->insl || current->dell)) + found = 1; + if (current->off + current->insl >= tmpcs || + current->hist != tmphist) { + tmpcs = current->off; + tmphist = current->hist; + if (current->insl) + tmpcs += current->insl - 1; + } else /* adjust tmpcs following this change */ + tmpcs += current->insl - current->dell; + } + if (!found) + return 1; + markcs = &tmpcs; + markhist = &tmphist; + } else if (ch == ZWC('.') && curchange->prev) { + /* position cursor where it was after the last change. not exactly + * what vim does but close enough */ + tmpcs = curchange->prev->new_cs; + tmphist = curchange->prev->hist; + markcs = &tmpcs; + markhist = &tmphist; + } else if (ch >= ZWC('a') && ch <= ZWC('z')) { + markhist = vimarkline + (ch - ZWC('a')); + markcs = vimarkcs + (ch - ZWC('a')); + } else return 1; + if (markhist) { + if (!*markhist) + return 1; + if (histline != *markhist && !zle_goto_hist(*markhist, 0, 0)) { + *markhist = 0; + return 1; + } } - zlecs = vimarkcs[ch]; + zlecs = *markcs; vimarkcs[26] = oldcs; vimarkline[26] = oldline; if (zlecs > zlell) diff --git a/Test/X02zlevi.ztst b/Test/X02zlevi.ztst index 14bc02e..21d22b1 100644 --- a/Test/X02zlevi.ztst +++ b/Test/X02zlevi.ztst @@ -289,6 +289,22 @@ >BUFFER: one wo >CURSOR: 2 + zletest $'one two three\e`[~wcenew\e`[~$p`[~$rO`[' +0:move to start of change with `[ +>BUFFER: One New threeTwO +>CURSOR: 15 + + zletest $'one\eyyPj`.~``cetwo\e0`.' +0:return to position after last change +>BUFFER: One +>two +>CURSOR: 6 + + zletest $'one two three\e0`]~bbcenew\e0`]~0P`]~0rO`]' +0:move to end of change with `] +>BUFFER: OwOone neW threE +>CURSOR: 0 + zletest $'keepnot\eo unwanted\ekhhcvj ' 0:force character-wise change to join lines >BUFFER: keep wanted