1
0
Fork 0
mirror of git://git.code.sf.net/p/zsh/code synced 2025-09-04 10:41:11 +02:00

24819: fix transposing characters and sneaky combination generation

This commit is contained in:
Peter Stephenson 2008-04-15 16:49:55 +00:00
parent fe6d34f024
commit 1875c12734
5 changed files with 139 additions and 37 deletions

View file

@ -1,3 +1,10 @@
2008-04-15 Peter Stephenson <pws@csr.com>
* : Src/Zle/zle.h, Src/Zle/zle_misc.c, Src/Zle/zle_move.c,
Src/Zle/zle_utils.c: need to fix up combining character aligment
in case of sneaky combination generation; fix transposing
characters.
2008-04-14 Peter Stephenson <pws@csr.com>
* 24816: Src/Zle/zle_hist.c, Src/Zle/zle_misc.c,

View file

@ -75,14 +75,19 @@ typedef wint_t ZLE_INT_T;
#define LASTFULLCHAR_T ZLE_INT_T
/* We may need to handle combining character alignment */
#define CCLEFT() alignmultiwordleft(1)
#define CCRIGHT() alignmultiwordright(1)
#define CCLEFT() alignmultiwordleft(&zlecs, 1)
#define CCRIGHT() alignmultiwordright(&zlecs, 1)
/*
* Increment or decrement the cursor position, skipping over
* combining characters.
*/
#define INCCS() inccs()
#define DECCS() deccs()
/*
* Same for any other position.
*/
#define INCPOS(pos) incpos(&pos)
#define DECPOS(pos) decpos(&pos)
#else /* Not MULTIBYTE_SUPPORT: old single-byte code */
@ -151,6 +156,11 @@ static inline int ZS_strncmp(ZLE_STRING_T s1, ZLE_STRING_T s2, size_t l)
*/
#define INCCS() ((void)(zlecs++))
#define DECCS() ((void)(zlecs--))
/*
* Same for any other position.
*/
#define INCPOS(pos) ((void)(pos++))
#define DECPOS(pos) ((void)(pos--))
#endif

View file

@ -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;
}

View file

@ -46,27 +46,27 @@ static int vimarkcs[27], vimarkline[27];
*/
/**/
int
alignmultiwordleft(int setpos)
alignmultiwordleft(int *pos, int setpos)
{
int loccs;
int loccs = *pos;
/* generic nothing to do test */
if (!isset(COMBININGCHARS) || zlecs == zlell || zlecs == 0)
if (!isset(COMBININGCHARS) || loccs == zlell || loccs == 0)
return 0;
/* need to be on zero-width punctuation character */
if (!iswpunct(zleline[zlecs]) || wcwidth(zleline[zlecs]) != 0)
if (!iswpunct(zleline[loccs]) || wcwidth(zleline[loccs]) != 0)
return 0;
/* yes, go left */
loccs = zlecs - 1;
loccs--;
for (;;) {
/* second test here is paranoia */
if (iswalnum(zleline[loccs]) && wcwidth(zleline[loccs]) > 0) {
/* found start position */
if (setpos)
zlecs = loccs;
*pos = loccs;
return 1;
} else if (!iswpunct(zleline[loccs]) ||
wcwidth(zleline[loccs]) != 0) {
@ -88,30 +88,31 @@ alignmultiwordleft(int setpos)
*/
/**/
int
alignmultiwordright(int setpos)
alignmultiwordright(int *pos, int setpos)
{
int loccs;
/*
* Are we on a suitable character?
*/
if (!alignmultiwordleft(0))
if (!alignmultiwordleft(pos, 0))
return 0;
/* yes, go right */
loccs = zlecs + 1;
loccs = *pos + 1;
while (loccs < zlell) {
/* Anything other than a combining char will do here */
if (!iswpunct(zleline[loccs]) || wcwidth(zleline[loccs]) != 0) {
if (setpos)
zlecs = loccs;
*pos = loccs;
return 1;
}
loccs++;
}
zlecs = zlell;
if (setpos)
*pos = loccs;
return 1;
}
@ -123,7 +124,7 @@ mod_export void
inccs(void)
{
zlecs++;
alignmultiwordright(1);
alignmultiwordright(&zlecs, 1);
}
@ -134,7 +135,26 @@ mod_export void
deccs(void)
{
zlecs--;
alignmultiwordleft(1);
alignmultiwordleft(&zlecs, 1);
}
/* Same utilities for general position */
/**/
mod_export void
incpos(int *pos)
{
(*pos)++;
alignmultiwordright(pos, 1);
}
/**/
mod_export void
decpos(int *pos)
{
(*pos)--;
alignmultiwordleft(pos, 1);
}
#endif

View file

@ -551,6 +551,7 @@ backkill(int ct, int flags)
cut(i, ct, flags);
shiftchars(i, ct);
CCRIGHT();
}
/**/
@ -569,6 +570,7 @@ forekill(int ct, int flags)
cut(i, ct, flags);
shiftchars(i, ct);
CCRIGHT();
}
/**/
@ -588,6 +590,7 @@ backdel(int ct, int flags)
DECCS();
shiftchars(zlecs, origcs - zlecs);
}
CCRIGHT();
}
/**/
@ -603,13 +606,14 @@ foredel(int ct, int flags)
} else {
int origcs = zlecs;
int n = ct;
DPUTS(zlemetaline != NULL, "backdel needs CUT_RAW when metafied");
DPUTS(zlemetaline != NULL, "foredel needs CUT_RAW when metafied");
while (n--)
INCCS();
ct = zlecs - origcs;
zlecs = origcs;
shiftchars(zlecs, ct);
}
CCRIGHT();
}
/**/
@ -634,6 +638,7 @@ setline(char *s, int flags)
DECCS();
else if (zlecs > zlell)
zlecs = zlell;
CCRIGHT();
if (flags & ZSL_COPY)
free(scp);