diff options
author | Peter Stephenson <pws@users.sourceforge.net> | 2008-04-17 12:52:13 +0000 |
---|---|---|
committer | Peter Stephenson <pws@users.sourceforge.net> | 2008-04-17 12:52:13 +0000 |
commit | 72bd9ee6d92ef8521a7a4b4f2f658940906d5c4f (patch) | |
tree | c369e585b693247720fafb00adf8bdc3d871d92f | |
parent | 78ce07b49f08964eaa08d68eb8f6a5595bbcfbc6 (diff) | |
download | zsh-72bd9ee6d92ef8521a7a4b4f2f658940906d5c4f.tar.gz zsh-72bd9ee6d92ef8521a7a4b4f2f658940906d5c4f.tar.xz zsh-72bd9ee6d92ef8521a7a4b4f2f658940906d5c4f.zip |
24825: fix internal word-boundary widgets
-rw-r--r-- | ChangeLog | 4 | ||||
-rw-r--r-- | Src/Zle/zle_word.c | 313 | ||||
-rw-r--r-- | Src/utils.c | 11 |
3 files changed, 236 insertions, 92 deletions
diff --git a/ChangeLog b/ChangeLog index 45acd817d..bd7f13e38 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,9 @@ 2008-04-17 Peter Stephenson <pws@csr.com> + * 24825: Src/utils.c, Src/Zle/zle_word.c: fix internal + word-boundary widgets and make zero-width punctuation + characters always part of a word. + * unposted: NEWS: list new features so far since 4.3.6. * Vincent Lefevre: 24818: Doc/Zsh/options.yo (modified), diff --git a/Src/Zle/zle_word.c b/Src/Zle/zle_word.c index c1fff7213..ef8220056 100644 --- a/Src/Zle/zle_word.c +++ b/Src/Zle/zle_word.c @@ -31,9 +31,13 @@ #include "zle_word.pro" /* - * HERE: our handling of combining characters may be wrong. We - * should make sure we only consider a combining character part of - * a word if the base character is. + * In principle we shouldn't consider a zero-length punctuation + * character (i.e. a modifier of some sort) part of the word unless + * the base character has. However, we only consider them part of + * a word if we so consider all alphanumerics, so the distinction + * only applies if the characters are modifying something they probably + * ought not to be modifying. It's not really clear we need to + * be clever about this not very useful case. */ /**/ @@ -147,11 +151,20 @@ viforwardblankwordend(UNUSED(char **args)) if (n < 0) return 1; while (n--) { - /* HERE: the zlecs + 1 here is suspect */ - while (zlecs != zlell && ZC_iblank(zleline[zlecs + 1])) - INCCS(); - while (zlecs != zlell && !ZC_iblank(zleline[zlecs + 1])) - INCCS(); + while (zlecs != zlell) { + int pos = zlecs; + INCPOS(pos); + if (!ZC_iblank(zleline[pos])) + break; + zlecs = pos; + } + while (zlecs != zlell) { + int pos = zlecs; + INCPOS(pos); + if (ZC_iblank(zleline[pos])) + break; + zlecs = pos; + } } if (zlecs != zlell && virangeflag) INCCS(); @@ -173,15 +186,37 @@ viforwardwordend(char **args) } while (n--) { /* HERE: the zlecs + 1 here is suspect */ - if (ZC_iblank(zleline[zlecs + 1])) - while (zlecs != zlell && ZC_iblank(zleline[zlecs + 1])) - INCCS(); - if (Z_vialnum(zleline[zlecs + 1])) - while (zlecs != zlell && Z_vialnum(zleline[zlecs + 1])) - INCCS(); - else - while (zlecs != zlell && !Z_vialnum(zleline[zlecs + 1]) && !ZC_iblank(zleline[zlecs + 1])) - INCCS(); + int pos; + while (zlecs != zlell) { + pos = zlecs; + INCPOS(pos); + if (!ZC_inblank(zleline[pos])) + break; + zlecs = pos; + } + if (zlecs != zlell) { + pos = zlecs; + INCPOS(pos); + if (Z_vialnum(zleline[pos])) { + for (;;) { + zlecs = pos; + if (zlecs == zlell) + break; + INCPOS(pos); + if (!Z_vialnum(zleline[pos])) + break; + } + } else { + for (;;) { + zlecs = pos; + if (zlecs == zlell) + break; + INCPOS(pos); + if (Z_vialnum(zleline[pos]) || ZC_iblank(zleline[pos])) + break; + } + } + } } if (zlecs != zlell && virangeflag) INCCS(); @@ -202,11 +237,20 @@ backwardword(char **args) return ret; } while (n--) { - /* HERE: the zlecs - 1 here is suspect */ - while (zlecs && !ZC_iword(zleline[zlecs - 1])) - DECCS(); - while (zlecs && ZC_iword(zleline[zlecs - 1])) - DECCS(); + while (zlecs) { + int pos = zlecs; + DECPOS(pos); + if (ZC_iword(zleline[pos])) + break; + zlecs = pos; + } + while (zlecs) { + int pos = zlecs; + DECPOS(pos); + if (!ZC_iword(zleline[pos])) + break; + zlecs = pos; + } } return 0; } @@ -225,15 +269,36 @@ vibackwardword(char **args) return ret; } while (n--) { - /* HERE: the zlecs - 1 here is suspect */ - while (zlecs && ZC_iblank(zleline[zlecs - 1])) - DECCS(); - if (Z_vialnum(zleline[zlecs - 1])) - while (zlecs && Z_vialnum(zleline[zlecs - 1])) - DECCS(); - else - while (zlecs && !Z_vialnum(zleline[zlecs - 1]) && !ZC_iblank(zleline[zlecs - 1])) - DECCS(); + while (zlecs) { + int pos = zlecs; + DECPOS(pos); + if (!ZC_iblank(zleline[pos])) + break; + zlecs = pos; + } + if (zlecs) { + int pos = zlecs; + DECPOS(pos); + if (Z_vialnum(zleline[pos])) { + for (;;) { + zlecs = pos; + if (zlecs == 0) + break; + DECPOS(pos); + if (!Z_vialnum(zleline[pos])) + break; + } + } else { + for (;;) { + zlecs = pos; + if (zlecs == 0) + break; + DECPOS(pos); + if (Z_vialnum(zleline[pos]) || ZC_iblank(zleline[pos])) + break; + } + } + } } return 0; } @@ -252,10 +317,20 @@ vibackwardblankword(char **args) return ret; } while (n--) { - while (zlecs && ZC_iblank(zleline[zlecs - 1])) - DECCS(); - while (zlecs && !ZC_iblank(zleline[zlecs - 1])) - DECCS(); + while (zlecs) { + int pos = zlecs; + DECPOS(pos); + if (!ZC_iblank(zleline[pos])) + break; + zlecs = pos; + } + while (zlecs) { + int pos = zlecs; + DECPOS(pos); + if (ZC_iblank(zleline[pos])) + break; + zlecs = pos; + } } return 0; } @@ -274,10 +349,20 @@ emacsbackwardword(char **args) return ret; } while (n--) { - while (zlecs && !ZC_iword(zleline[zlecs - 1])) - DECCS(); - while (zlecs && ZC_iword(zleline[zlecs - 1])) - DECCS(); + while (zlecs) { + int pos = zlecs; + DECPOS(pos); + if (ZC_iword(zleline[pos])) + break; + zlecs = pos; + } + while (zlecs) { + int pos = zlecs; + DECPOS(pos); + if (!ZC_iword(zleline[pos])) + break; + zlecs = pos; + } } return 0; } @@ -296,14 +381,20 @@ backwarddeleteword(char **args) return ret; } while (n--) { - /* - * HERE: the zlecs - 1 here is suspect, and we should - * do the DECCS() thing. - */ - while (x && !ZC_iword(zleline[x - 1])) - x--; - while (x && ZC_iword(zleline[x - 1])) - x--; + while (x) { + int pos = x; + DECPOS(pos); + if (ZC_iword(zleline[pos])) + break; + x = pos; + } + while (x) { + int pos = x; + DECPOS(pos); + if (!ZC_iword(zleline[pos])) + break; + x = pos; + } } backdel(zlecs - x, CUT_RAW); return 0; @@ -320,18 +411,36 @@ vibackwardkillword(UNUSED(char **args)) return 1; /* this taken from "vibackwardword" */ while (n--) { - /* - * HERE: the zlecs - 1 here is suspect, and we should - * do the DECCS() thing. - */ - while ((x > lim) && ZC_iblank(zleline[x - 1])) - x--; - if (Z_vialnum(zleline[x - 1])) - while ((x > lim) && Z_vialnum(zleline[x - 1])) - x--; - else - while ((x > lim) && !Z_vialnum(zleline[x - 1]) && !ZC_iblank(zleline[x - 1])) - x--; + while (x > lim) { + int pos = x; + DECPOS(pos); + if (!ZC_iblank(zleline[pos])) + break; + x = pos; + } + if (x > lim) { + int pos = x; + DECPOS(pos); + if (Z_vialnum(zleline[pos])) { + for (;;) { + x = pos; + if (x <= lim) + break; + DECPOS(pos); + if (!Z_vialnum(zleline[pos])) + break; + } + } else { + for (;;) { + x = pos; + if (x <= lim) + break; + DECPOS(pos); + if (Z_vialnum(zleline[pos]) || ZC_iblank(zleline[pos])) + break; + } + } + } } backkill(zlecs - x, CUT_FRONT); return 0; @@ -352,14 +461,20 @@ backwardkillword(char **args) return ret; } while (n--) { - /* - * HERE: the zlecs - 1 here is suspect, and we should - * do the DECCS() thing. - */ - while (x && !ZC_iword(zleline[x - 1])) - x--; - while (x && ZC_iword(zleline[x - 1])) - x--; + while (x) { + int pos = x; + DECPOS(pos); + if (ZC_iword(zleline[x])) + break; + x = pos; + } + while (x) { + int pos = x; + DECPOS(pos); + if (!ZC_iword(zleline[x])) + break; + x = pos; + } } backkill(zlecs - x, CUT_FRONT); return 0; @@ -451,11 +566,10 @@ deleteword(char **args) return ret; } while (n--) { - /* HERE: we should do the INCCS() thing */ while (x != zlell && !ZC_iword(zleline[x])) - x++; + INCPOS(x); while (x != zlell && ZC_iword(zleline[x])) - x++; + INCPOS(x); } foredel(x - zlecs, CUT_RAW); return 0; @@ -476,11 +590,10 @@ killword(char **args) return ret; } while (n--) { - /* HERE: we should do the INCCS() thing */ while (x != zlell && !ZC_iword(zleline[x])) - x++; + INCPOS(x); while (x != zlell && ZC_iword(zleline[x])) - x++; + INCPOS(x); } forekill(x - zlecs, CUT_RAW); return 0; @@ -490,7 +603,7 @@ killword(char **args) int transposewords(UNUSED(char **args)) { - int p1, p2, p3, p4, len, x = zlecs; + int p1, p2, p3, p4, len, x = zlecs, pos; ZLE_STRING_T temp, pp; int n = zmult; int neg = n < 0, ocs = zlecs; @@ -498,28 +611,54 @@ transposewords(UNUSED(char **args)) if (neg) n = -n; while (n--) { - /* - * HERE: we should do the INCCS() thing. - * A great deal of the following needs rewriting. - */ while (x != zlell && zleline[x] != ZWC('\n') && !ZC_iword(zleline[x])) - x++; + INCPOS(x); if (x == zlell || zleline[x] == ZWC('\n')) { x = zlecs; - while (x && zleline[x - 1] != ZWC('\n') && !ZC_iword(zleline[x])) - x--; - if (!x || zleline[x - 1] == ZWC('\n')) + while (x) { + if (ZC_iword(zleline[x])) + break; + pos = x; + DECPOS(pos); + if (zleline[pos] == ZWC('\n')) + break; + x = pos; + } + if (!x) + return 1; + pos = x; + DECPOS(pos); + if (zleline[pos] == ZWC('\n')) return 1; + x = pos; + } + for (p4 = x; p4 != zlell && ZC_iword(zleline[p4]); INCPOS(p4)) + ; + for (p3 = p4; p3; ) { + pos = p3; + DECPOS(pos); + if (!ZC_iword(zleline[pos])) + break; + p3 = pos; } - for (p4 = x; p4 != zlell && ZC_iword(zleline[p4]); p4++); - for (p3 = p4; p3 && ZC_iword(zleline[p3 - 1]); p3--); if (!p3) return 1; - for (p2 = p3; p2 && !ZC_iword(zleline[p2 - 1]); p2--); + for (p2 = p3; p2; ) { + pos = p2; + DECPOS(pos); + if (ZC_iword(zleline[pos])) + break; + p2 = pos; + } if (!p2) return 1; - for (p1 = p2; p1 && ZC_iword(zleline[p1 - 1]); p1--); - + for (p1 = p2; p1; ) { + pos = p1; + DECPOS(pos); + if (!ZC_iword(zleline[pos])) + break; + p1 = pos; + } pp = temp = (ZLE_STRING_T)zhalloc((p4 - p1)*ZLE_CHAR_SIZE); len = p4 - p3; ZS_memcpy(pp, zleline + p3, len); diff --git a/Src/utils.c b/Src/utils.c index b4770befe..21a3a0c34 100644 --- a/Src/utils.c +++ b/Src/utils.c @@ -3082,12 +3082,13 @@ wcsitype(wchar_t c, int itype) if (iswalnum(c)) return 1; /* - * If we are handling combining characters, anything - * printable with zero width needs to be considered - * part of a word. + * If we are handling combining characters, any punctuation + * characters with zero width needs to be considered part of + * a word. If we are not handling combining characters then + * logically they are still part of the word, even if they + * don't get displayed properly, so always do this. */ - if (isset(COMBININGCHARS) && - iswprint(c) && wcwidth(c) == 0) + if (iswpunct(c) && wcwidth(c) == 0) return 1; return !!wmemchr(wordchars_wide.chars, c, wordchars_wide.len); |