* vi-backward-kill-word @ 2008-04-21 16:10 Jun T. 2008-04-21 17:27 ` vi-backward-kill-word Peter Stephenson 0 siblings, 1 reply; 6+ messages in thread From: Jun T. @ 2008-04-21 16:10 UTC (permalink / raw) To: zsh-workers Since you wrote in your first post: >Known gaps at the moment: >- Word tests need improving (a whole smattering HEREs) >- Vi "r" needs some work (another HERE) I guess you already know that vi "r" and "R" do not work properly on combined character(s). Another minor problem is, when in vi-insert mode, ^W (vi-backward-kill-word) kills wrong part of the line if the word to be killed contains combined character. zsh -f bindkey -v echo é<^W> echó (Here é is in decomposed form: e + U+0301). The word "é" must be killed, but what is actually killed is " e" (a space and "e"), leaving the combining character. It *seems* it can be fixed by replacing the line 44 of zle_word.c backkill(zlecs - x, CUT_FRONT); by backkill(zlecs - x, CUT_FRONT|CUT_RAW); In the present case, the comgining character(s) are already taken accout of by vibackwardkillword(), and 'zlecs - x' is the number of wchar_t to be killed. So I *guess* CUT_RAW should be used here. Am I right? # I guess you are busy working on many problems. # I fear I'm disturbing you... ^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: vi-backward-kill-word 2008-04-21 16:10 vi-backward-kill-word Jun T. @ 2008-04-21 17:27 ` Peter Stephenson 2008-04-21 17:57 ` vi-backward-kill-word Peter Stephenson 2008-04-22 17:56 ` vi-backward-kill-word Jun T. 0 siblings, 2 replies; 6+ messages in thread From: Peter Stephenson @ 2008-04-21 17:27 UTC (permalink / raw) To: zsh-workers On Tue, 22 Apr 2008 01:10:40 +0900 "Jun T." <takimoto-j@kba.biglobe.ne.jp> wrote: > Since you wrote in your first post: > >Known gaps at the moment: > >- Word tests need improving (a whole smattering HEREs) > >- Vi "r" needs some work (another HERE) > > I guess you already know that vi "r" and "R" do not work properly > on combined character(s). I would have if I'd thought about it. The problem with R was actually generic to overstrike (non-insert) mode. I think there's still a problem in overstrike mode when you enter a combining character; it'll advance too far right. I'll look at that separately. It's still the case that you can't use r and R with characters with combining characters as arguments. That's quite tough, since you don't know they're are going to be any to read after the base character when reading from the terminal. We could use a timeout, I suppose, but even so it would need a whole new layer of character input. > Another minor problem is, when in vi-insert mode, ^W > (vi-backward-kill-word) kills wrong part of the line if the word > to be killed contains combined character. >... > It *seems* it can be fixed by replacing the line 44 of zle_word.c > backkill(zlecs - x, CUT_FRONT); > by > backkill(zlecs - x, CUT_FRONT|CUT_RAW); Yep, that looks right... the CUT_RAW is needed any time the first argument is a number of raw characters in the buffer, which it must be if it's a difference of positions. In fact, CUT_RAW should really be the default because there are only very few places where the number comes directly from the user where it isn't wanted. I also found that vi-put-after (p) wasn't working for the usual reason to do with character positions. > # I guess you are busy working on many problems. > # I fear I'm disturbing you... Actually, I'd quite like to get the combining characters sorted out as soon as possible. Index: Src/Zle/zle_misc.c =================================================================== RCS file: /cvsroot/zsh/zsh/Src/Zle/zle_misc.c,v retrieving revision 1.49 diff -u -r1.49 zle_misc.c --- Src/Zle/zle_misc.c 20 Apr 2008 21:23:14 -0000 1.49 +++ Src/Zle/zle_misc.c 21 Apr 2008 17:19:56 -0000 @@ -47,14 +47,27 @@ iremovesuffix(c1, 0); invalidatelist(); - if(insmode) + if (insmode) spaceinline(m * len); - else if(zlecs + m * len > zlell) - spaceinline(zlecs + m * len - zlell); - while(m--) + else { + int pos = zlecs, count = m * len, i = count, diff; + /* + * Ensure we replace a complete combining character + * for each character we overwrite. + */ + while (pos < zlell && i--) { + INCPOS(pos); + } + diff = pos - zlecs - count; + if (diff < 0) { + spaceinline(-diff); + } else if (diff > 0) + foredel(diff, CUT_RAW); + } + while (m--) for(s = zstr, count = len; count; s++, count--) zleline[zlecs++] = *s; - if(neg) + if (neg) zlecs += zmult * len; /* if we ended up on a combining character, skip over it */ CCRIGHT(); Index: Src/Zle/zle_vi.c =================================================================== RCS file: /cvsroot/zsh/zsh/Src/Zle/zle_vi.c,v retrieving revision 1.19 diff -u -r1.19 zle_vi.c --- Src/Zle/zle_vi.c 20 Apr 2008 21:17:30 -0000 1.19 +++ Src/Zle/zle_vi.c 21 Apr 2008 17:19:59 -0000 @@ -498,18 +498,19 @@ vireplacechars(UNUSED(char **args)) { ZLE_INT_T ch; - int n = zmult, origcs = zlecs, fail = 0; + int n = zmult, fail = 0, newchars = 0; if (n > 0) { + int pos = zlecs; while (n-- > 0) { - if (zlecs == zlell || zleline[zlell] == ZWC('\n')) { + if (pos == zlell || zleline[pos] == ZWC('\n')) { fail = 1; break; } - INCCS(); + newchars++; + INCPOS(pos); } - n = zlecs - origcs; - zlecs = origcs; + n = pos - zlecs; } startvichange(1); /* check argument range */ @@ -535,8 +536,16 @@ backkill(n - 1, CUT_RAW); zleline[zlecs++] = '\n'; } else { - /* HERE: we shouldn't replace combining chars, we should delete them */ - while (n--) + /* + * Make sure we delete displayed characters, including + * attach combining characters. n includes this as a raw + * buffer offset. + */ + if (n > newchars) + foredel(n - newchars, CUT_RAW); + else if (n < newchars) + spaceinline(newchars - n); + while (newchars--) zleline[zlecs++] = ch; zlecs--; } @@ -792,14 +801,14 @@ vifirstnonblank(zlenoargs); } else { if (zlecs != findeol()) - zlecs++; + INCCS(); while (n--) { spaceinline(buf->len); ZS_memcpy(zleline + zlecs, buf->buf, buf->len); zlecs += buf->len; } if (zlecs) - zlecs--; + DECCS(); } return 0; } Index: Src/Zle/zle_word.c =================================================================== RCS file: /cvsroot/zsh/zsh/Src/Zle/zle_word.c,v retrieving revision 1.13 diff -u -r1.13 zle_word.c --- Src/Zle/zle_word.c 20 Apr 2008 21:17:30 -0000 1.13 +++ Src/Zle/zle_word.c 21 Apr 2008 17:20:00 -0000 @@ -441,7 +441,7 @@ } } } - backkill(zlecs - x, CUT_FRONT); + backkill(zlecs - x, CUT_FRONT|CUT_RAW); return 0; } @@ -475,7 +475,7 @@ x = pos; } } - backkill(zlecs - x, CUT_FRONT); + backkill(zlecs - x, CUT_FRONT|CUT_RAW); return 0; } -- Peter Stephenson <pws@csr.com> Software Engineer CSR PLC, Churchill House, Cambridge Business Park, Cowley Road Cambridge, CB4 0WZ, UK Tel: +44 (0)1223 692070 ^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: vi-backward-kill-word 2008-04-21 17:27 ` vi-backward-kill-word Peter Stephenson @ 2008-04-21 17:57 ` Peter Stephenson 2008-04-22 17:56 ` vi-backward-kill-word Jun T. 1 sibling, 0 replies; 6+ messages in thread From: Peter Stephenson @ 2008-04-21 17:57 UTC (permalink / raw) To: zsh-workers On Mon, 21 Apr 2008 18:27:28 +0100 Peter Stephenson <pws@csr.com> wrote: > I think there's still a problem > in overstrike mode when you enter a combining character; it'll advance too > far right. I'll look at that separately. I think this deals with it. I saw some oddities with undo, but that may simply be because in a version I hadn't quite got right the cursor position was screwy. I didn't see them with the final version. Index: Src/Zle/zle_misc.c =================================================================== RCS file: /cvsroot/zsh/zsh/Src/Zle/zle_misc.c,v retrieving revision 1.50 diff -u -r1.50 zle_misc.c --- Src/Zle/zle_misc.c 21 Apr 2008 17:30:35 -0000 1.50 +++ Src/Zle/zle_misc.c 21 Apr 2008 17:53:42 -0000 @@ -50,19 +50,43 @@ if (insmode) spaceinline(m * len); else { - int pos = zlecs, count = m * len, i = count, diff; + int pos = zlecs, diff, i; + + /* + * Calculate the number of character positions we are + * going to be using. The algorithm is that + * anything that shows up as a logical single character + * (i.e. even if control, or double width, or with combining + * characters) is treated as 1 for the purpose of replacing + * what's there already. + */ + for (i = 0, count = 0; i < len; i++) { + int width = wcwidth(zstr[i]); + count += (width != 0) ? 1 : 0; + } /* * Ensure we replace a complete combining character * for each character we overwrite. */ - while (pos < zlell && i--) { + for (i = count; pos < zlell && i--; ) { INCPOS(pos); } - diff = pos - zlecs - count; + /* + * Calculate how many raw line places we need. + * pos - zlecs is the raw line distance we're replacing, + * m * len the number we're inserting. + */ + diff = pos - zlecs - m * len; if (diff < 0) { spaceinline(-diff); - } else if (diff > 0) - foredel(diff, CUT_RAW); + } else if (diff > 0) { + /* + * We use shiftchars() here because we don't + * want combining char alignment fixed up: we + * are going to write over any that remain. + */ + shiftchars(zlecs, diff); + } } while (m--) for (s = zstr, count = len; count; s++, count--) Index: Src/Zle/zle_utils.c =================================================================== RCS file: /cvsroot/zsh/zsh/Src/Zle/zle_utils.c,v retrieving revision 1.51 diff -u -r1.51 zle_utils.c --- Src/Zle/zle_utils.c 21 Apr 2008 10:13:31 -0000 1.51 +++ Src/Zle/zle_utils.c 21 Apr 2008 17:53:42 -0000 @@ -450,7 +450,7 @@ } /**/ -static void +void shiftchars(int to, int cnt) { if (mark >= to + cnt) -- Peter Stephenson <pws@csr.com> Software Engineer CSR PLC, Churchill House, Cambridge Business Park, Cowley Road Cambridge, CB4 0WZ, UK Tel: +44 (0)1223 692070 ^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: vi-backward-kill-word 2008-04-21 17:27 ` vi-backward-kill-word Peter Stephenson 2008-04-21 17:57 ` vi-backward-kill-word Peter Stephenson @ 2008-04-22 17:56 ` Jun T. 2008-04-23 8:32 ` vi-backward-kill-word Peter Stephenson 1 sibling, 1 reply; 6+ messages in thread From: Jun T. @ 2008-04-22 17:56 UTC (permalink / raw) To: zsh-workers Vi "r" seems to still have some problems. Suppose you have a command line like: echo aéo and move the cursor to é and type "rb". Then the command line will become echo áb In vireplacechars(), line 545 (zle_vi.c), foredel(n - newchars, CUT_RAW); this will remove the base character "e" at zlecs, shift the combining character, and move zlecs to the next base char "o". a e comb o | zlecs will become a comb o | zlecs and then "o" is replaced by "b". ^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: vi-backward-kill-word 2008-04-22 17:56 ` vi-backward-kill-word Jun T. @ 2008-04-23 8:32 ` Peter Stephenson 0 siblings, 0 replies; 6+ messages in thread From: Peter Stephenson @ 2008-04-23 8:32 UTC (permalink / raw) To: zsh-workers "Jun T." wrote: > In vireplacechars(), line 545 (zle_vi.c), > foredel(n - newchars, CUT_RAW); > > this will remove the base character "e" at zlecs, shift the > combining character, and move zlecs to the next base char "o". Yes, that needs to use shiftchars(), as I've already done in overwrite mode. Index: Src/Zle/zle_vi.c =================================================================== RCS file: /cvsroot/zsh/zsh/Src/Zle/zle_vi.c,v retrieving revision 1.20 diff -u -r1.20 zle_vi.c --- Src/Zle/zle_vi.c 21 Apr 2008 17:30:36 -0000 1.20 +++ Src/Zle/zle_vi.c 23 Apr 2008 08:31:48 -0000 @@ -540,9 +540,11 @@ * Make sure we delete displayed characters, including * attach combining characters. n includes this as a raw * buffer offset. + * Use shiftchars so as not to adjust the cursor position; + * we are overwriting anything that remains directly. */ if (n > newchars) - foredel(n - newchars, CUT_RAW); + shiftchars(zlecs, n - newchars); else if (n < newchars) spaceinline(newchars - n); while (newchars--) -- Peter Stephenson <pws@csr.com> Software Engineer CSR PLC, Churchill House, Cambridge Business Park, Cowley Road Cambridge, CB4 0WZ, UK Tel: +44 (0)1223 692070 ^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: vi-backward-kill-word @ 2008-04-24 10:35 Jun T. 0 siblings, 0 replies; 6+ messages in thread From: Jun T. @ 2008-04-24 10:35 UTC (permalink / raw) To: zsh-workers Another minor bug in vi mode. If you enter a combined char and delete it in vi-insert mode by ctrl-H (bound to vi-backward-delete-char), then only the base char is deleted. In this case, vibackwarddeletechar() calls backkill() without setting CUT_RAW flag. backkill() correclty finds the new zlecs but does not re-calculate the number of raw chars to be killed (the variable ct). A possible fix may be the following: Index: Src/Zle/zle_utils.c =================================================================== RCS file: /cvsroot/zsh/zsh/Src/Zle/zle_utils.c,v retrieving revision 1.52 diff -u -r1.52 zle_utils.c --- Src/Zle/zle_utils.c 21 Apr 2008 17:58:59 -0000 1.52 +++ Src/Zle/zle_utils.c 24 Apr 2008 09:48:38 -0000 @@ -589,20 +589,18 @@ mod_export void backkill(int ct, int flags) { - int i; - UNMETACHECK(); if (flags & CUT_RAW) { - i = (zlecs -= ct); + zlecs -= ct; } else { - int n = ct; - while (n--) + int origcs = zlecs; + while (ct--) DECCS(); - i = zlecs; + ct = origcs - zlecs; } - cut(i, ct, flags); - shiftchars(i, ct); + cut(zlecs, ct, flags); + shiftchars(zlecs, ct); CCRIGHT(); } ------ Jun ^ permalink raw reply [flat|nested] 6+ messages in thread
end of thread, other threads:[~2008-04-24 10:35 UTC | newest] Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed) -- links below jump to the message on this page -- 2008-04-21 16:10 vi-backward-kill-word Jun T. 2008-04-21 17:27 ` vi-backward-kill-word Peter Stephenson 2008-04-21 17:57 ` vi-backward-kill-word Peter Stephenson 2008-04-22 17:56 ` vi-backward-kill-word Jun T. 2008-04-23 8:32 ` vi-backward-kill-word Peter Stephenson 2008-04-24 10:35 vi-backward-kill-word Jun T.
Code repositories for project(s) associated with this public inbox https://git.vuxu.org/mirror/zsh/ This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for NNTP newsgroup(s).