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:
parent
fe6d34f024
commit
1875c12734
5 changed files with 139 additions and 37 deletions
|
@ -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,
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Reference in a new issue