Zsh Mailing List Archive
Messages sorted by:
Reverse Date,
Date,
Thread,
Author
Re: PATCH: (large) initial support for combining characters in ZLE.
- X-seq: zsh-workers 24819
- From: Peter Stephenson <pws@xxxxxxx>
- To: "Zsh Hackers' List" <zsh-workers@xxxxxxxxxx>
- Subject: Re: PATCH: (large) initial support for combining characters in ZLE.
- Date: Tue, 15 Apr 2008 17:46:45 +0100
- In-reply-to: <237967ef0804150658h1f8df5e5w422955fc6b92fe29@xxxxxxxxxxxxxx>
- Mailing-list: contact zsh-workers-help@xxxxxxxxxx; run by ezmlm
- Organization: CSR
- References: <20080413175442.0e95a241@pws-pc> <237967ef0804140634l7e02ce6fofff7f3f3ec6c8d7c@xxxxxxxxxxxxxx> <20080414145425.566bcb92@news01> <237967ef0804150658h1f8df5e5w422955fc6b92fe29@xxxxxxxxxxxxxx>
On Tue, 15 Apr 2008 15:58:54 +0200
"Mikael Magnusson" <mikachu@xxxxxxxxx> wrote:
> This is better, but I can still put the cursor between the a and the ~.
> > > % zsh -f
> > > % setopt combiningchars
> > > % print -z $'\u0342'
> > > the buffer should now contain an inverted <0342>, press left or ctrl-a
> > > or whatever to go to the start of the line and press 'a'.
> But instead of pressing a, type a '!' and go left again and press 'a',
> then press ctrl-d. (or ctrl-t)
OK, so we need to fix things up right at the end after an operation in case
it generated some combinations a sneaky way. Hence some more CCRIGHT()s.
> Another thing I noticed is that ctrl-t moves just the combining char,
> not the whole base+combiningchar, but that might already be on your
> todo as a subset of "fix widgets" :).
This should help with fixing the word stuff, when I get round to it...
I'm fed up with the names zle_misc.c and zle_utils.c. I can never find
anything.
Index: Src/Zle/zle.h
===================================================================
RCS file: /cvsroot/zsh/zsh/Src/Zle/zle.h,v
retrieving revision 1.37
diff -u -r1.37 zle.h
--- Src/Zle/zle.h 13 Apr 2008 16:58:42 -0000 1.37
+++ Src/Zle/zle.h 15 Apr 2008 16:42:04 -0000
@@ -75,14 +75,19 @@
#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 @@
*/
#define INCCS() ((void)(zlecs++))
#define DECCS() ((void)(zlecs--))
+/*
+ * Same for any other position.
+ */
+#define INCPOS(pos) ((void)(pos++))
+#define DECPOS(pos) ((void)(pos--))
#endif
Index: Src/Zle/zle_misc.c
===================================================================
RCS file: /cvsroot/zsh/zsh/Src/Zle/zle_misc.c,v
retrieving revision 1.46
diff -u -r1.46 zle_misc.c
--- Src/Zle/zle_misc.c 14 Apr 2008 14:57:54 -0000 1.46
+++ Src/Zle/zle_misc.c 15 Apr 2008 16:42:07 -0000
@@ -196,23 +196,66 @@
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 @@
int
transposechars(UNUSED(char **args))
{
- int cc, ct;
+ int ct;
int n = zmult;
int neg = n < 0;
@@ -231,26 +274,43 @@
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;
}
Index: Src/Zle/zle_move.c
===================================================================
RCS file: /cvsroot/zsh/zsh/Src/Zle/zle_move.c,v
retrieving revision 1.11
diff -u -r1.11 zle_move.c
--- Src/Zle/zle_move.c 13 Apr 2008 16:58:42 -0000 1.11
+++ Src/Zle/zle_move.c 15 Apr 2008 16:42:08 -0000
@@ -46,27 +46,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 @@
*/
/**/
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 @@
inccs(void)
{
zlecs++;
- alignmultiwordright(1);
+ alignmultiwordright(&zlecs, 1);
}
@@ -134,7 +135,26 @@
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
Index: Src/Zle/zle_utils.c
===================================================================
RCS file: /cvsroot/zsh/zsh/Src/Zle/zle_utils.c,v
retrieving revision 1.47
diff -u -r1.47 zle_utils.c
--- Src/Zle/zle_utils.c 13 Apr 2008 16:58:44 -0000 1.47
+++ Src/Zle/zle_utils.c 15 Apr 2008 16:42:12 -0000
@@ -551,6 +551,7 @@
cut(i, ct, flags);
shiftchars(i, ct);
+ CCRIGHT();
}
/**/
@@ -569,6 +570,7 @@
cut(i, ct, flags);
shiftchars(i, ct);
+ CCRIGHT();
}
/**/
@@ -588,6 +590,7 @@
DECCS();
shiftchars(zlecs, origcs - zlecs);
}
+ CCRIGHT();
}
/**/
@@ -603,13 +606,14 @@
} 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 @@
DECCS();
else if (zlecs > zlell)
zlecs = zlell;
+ CCRIGHT();
if (flags & ZSL_COPY)
free(scp);
--
Peter Stephenson <pws@xxxxxxx> Software Engineer
CSR PLC, Churchill House, Cambridge Business Park, Cowley Road
Cambridge, CB4 0WZ, UK Tel: +44 (0)1223 692070
Messages sorted by:
Reverse Date,
Date,
Thread,
Author