diff options
author | Peter Stephenson <pws@users.sourceforge.net> | 2008-04-15 16:49:55 +0000 |
---|---|---|
committer | Peter Stephenson <pws@users.sourceforge.net> | 2008-04-15 16:49:55 +0000 |
commit | 1875c12734938595033715a948f50b05b76bca3d (patch) | |
tree | 4b4bf3e48cddd2a8d5a3b187fde6772d424dfaa2 /Src/Zle/zle_misc.c | |
parent | fe6d34f024a20d57741b500a91649fa7032cc509 (diff) | |
download | zsh-1875c12734938595033715a948f50b05b76bca3d.tar.gz zsh-1875c12734938595033715a948f50b05b76bca3d.tar.xz zsh-1875c12734938595033715a948f50b05b76bca3d.zip |
24819: fix transposing characters and sneaky combination generation
Diffstat (limited to 'Src/Zle/zle_misc.c')
-rw-r--r-- | Src/Zle/zle_misc.c | 102 |
1 files changed, 81 insertions, 21 deletions
diff --git a/Src/Zle/zle_misc.c b/Src/Zle/zle_misc.c index fb03ee149..db2d4acce 100644 --- a/Src/Zle/zle_misc.c +++ b/Src/Zle/zle_misc.c @@ -196,23 +196,66 @@ backwardkillline(char **args) return 0; } +#ifdef MULTIBYTE_SUPPORT +/* + * Transpose the chunk of the line from start to middle with + * that from middle to end. + */ + +static void +transpose_swap(int start, int middle, int end) +{ + int len1, len2; + ZLE_STRING_T first; + + len1 = middle - start; + len2 = end - middle; + + first = (ZLE_STRING_T)zalloc(len1 * ZLE_CHAR_SIZE); + ZS_memcpy(first, zleline + start, len1); + /* Move may be overlapping... */ + ZS_memmove(zleline + start, zleline + middle, len2); + ZS_memcpy(zleline + start + len2, first, len1); + zfree(first, len1 * ZLE_CHAR_SIZE); +} +#endif + /**/ int gosmacstransposechars(UNUSED(char **args)) { - int cc; - if (zlecs < 2 || zleline[zlecs - 1] == '\n' || zleline[zlecs - 2] == '\n') { - if (zlecs == zlell || zleline[zlecs] == '\n' || - ((zlecs + 1 == zlell || zleline[zlecs + 1] == '\n') && - (!zlecs || zleline[zlecs - 1] == '\n'))) { + int twice = (zlecs == 0 || zleline[zlecs - 1] == '\n'); + + if (zlecs == zlell || zleline[zlecs] == '\n') return 1; + + INCCS(); + if (twice) { + if (zlecs == zlell || zleline[zlecs] == '\n') + return 1; + INCCS(); } - zlecs += (zlecs == 0 || zleline[zlecs - 1] == '\n') ? 2 : 1; } - cc = zleline[zlecs - 2]; - zleline[zlecs - 2] = zleline[zlecs - 1]; - zleline[zlecs - 1] = cc; +#ifdef MULTIBYTE_SUPPORT + { + int start, middle; + + middle = zlecs; + DECPOS(middle); + + start = middle; + DECPOS(start); + + transpose_swap(start, middle, zlecs); + } +#else + { + ZLE_CHAR_T cc = zleline[zlecs - 2]; + zleline[zlecs - 2] = zleline[zlecs - 1]; + zleline[zlecs - 1] = cc; + } +#endif return 0; } @@ -220,7 +263,7 @@ gosmacstransposechars(UNUSED(char **args)) int transposechars(UNUSED(char **args)) { - int cc, ct; + int ct; int n = zmult; int neg = n < 0; @@ -231,26 +274,43 @@ transposechars(UNUSED(char **args)) if (zlell == zlecs || zleline[zlecs] == '\n') return 1; if (!neg) - zlecs++; - ct++; + INCCS(); + INCPOS(ct); } if (neg) { if (zlecs && zleline[zlecs - 1] != '\n') { - zlecs--; - if (ct > 1 && zleline[ct - 2] != '\n') - ct--; + DECCS(); + if (ct > 1 && zleline[ct - 2] != '\n') { + DECPOS(ct); + } } } else { if (zlecs != zlell && zleline[zlecs] != '\n') - zlecs++; + INCCS(); + } + if (ct == zlell || zleline[ct] == '\n') { + DECPOS(ct); } - if (ct == zlell || zleline[ct] == '\n') - ct--; if (ct < 1 || zleline[ct - 1] == '\n') return 1; - cc = zleline[ct - 1]; - zleline[ct - 1] = zleline[ct]; - zleline[ct] = cc; +#ifdef MULTIBYTE_SUPPORT + { + /* + * We should keep any accents etc. on their original characters. + */ + int start = ct, end = ct; + DECPOS(start); + INCPOS(end); + + transpose_swap(start, ct, end); + } +#else + { + ZLE_CHAR_T cc = zleline[ct - 1]; + zleline[ct - 1] = zleline[ct]; + zleline[ct] = cc; + } +#endif } return 0; } |