summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog8
-rw-r--r--Doc/Zsh/zle.yo8
-rw-r--r--Src/Zle/zle_keymap.c2
-rw-r--r--Src/Zle/zle_main.c47
-rw-r--r--Src/Zle/zle_misc.c2
-rw-r--r--Src/Zle/zle_vi.c2
-rw-r--r--Src/builtin.c6
-rw-r--r--Src/init.c2
8 files changed, 61 insertions, 16 deletions
diff --git a/ChangeLog b/ChangeLog
index d3a8c8289..21469f438 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,11 @@
+2005-09-09 Peter Stephenson <pws@csr.com>
+
+ * 21709 plus tweaks: Doc/Zsh/zle.yo, Src/builtin.c, Src/init.c,
+ Src/Zle/zle_keymap.c, Src/Zle/zle_main.c, Src/Zle/zle_misc.c,
+ Src/Zle/zle_vi.c: Use $KEYTIMOUT for bytes after the first
+ in a multibyte character. Reset input state on invalid
+ character or EOF.
+
2005-09-07 Clint Adams <clint@zsh.org>
* 21704, 21705: Completion/Unix/Command/_date: completion for
diff --git a/Doc/Zsh/zle.yo b/Doc/Zsh/zle.yo
index 048cba576..1daffde00 100644
--- a/Doc/Zsh/zle.yo
+++ b/Doc/Zsh/zle.yo
@@ -87,6 +87,14 @@ execute the binding. This timeout is defined by the tt(KEYTIMEOUT) parameter;
its default is 0.4 sec. There is no timeout if the prefix string is not
itself bound to a command.
+The key timeout is also applied when ZLE is reading the bytes from a
+multibyte character string when it is in the appropriate mode. (This
+requires that the shell was compiled with multibyte mode enabled; typically
+also the locale has characters with the UTF-8 encoding, although any
+multibyte encoding known to the operating system is supported.) If the
+second or a subsequent byte is not read within the timeout period, the
+shell acts as if tt(?) were typed and resets the input state.
+
As well as ZLE commands, key sequences can be bound to other strings, by using
`tt(bindkey -s)'.
When such a sequence is read, the replacement string is pushed back as input,
diff --git a/Src/Zle/zle_keymap.c b/Src/Zle/zle_keymap.c
index 6f4e062fc..376805549 100644
--- a/Src/Zle/zle_keymap.c
+++ b/Src/Zle/zle_keymap.c
@@ -1341,7 +1341,7 @@ getkeymapcmd(Keymap km, Thingy *funcp, char **strp)
static int
getkeybuf(int w)
{
- int c = getbyte(w);
+ int c = getbyte(w, NULL);
if(c < 0)
return EOF;
diff --git a/Src/Zle/zle_main.c b/Src/Zle/zle_main.c
index 2522f67fd..4f598b889 100644
--- a/Src/Zle/zle_main.c
+++ b/Src/Zle/zle_main.c
@@ -628,13 +628,16 @@ raw_getbyte(int keytmout, char *cptr)
/**/
mod_export int
-getbyte(int keytmout)
+getbyte(int keytmout, int *timeout)
{
char cc;
unsigned int ret;
int die = 0, r, icnt = 0;
int old_errno = errno, obreaks = breaks;
+ if (timeout)
+ *timeout = 0;
+
#ifdef ZLE_UNICODE_SUPPORT
/*
* Reading a single byte always invalidates the status
@@ -660,8 +663,12 @@ getbyte(int keytmout)
dont_queue_signals();
r = raw_getbyte(keytmout, &cc);
restore_queue_signals(q);
- if (r == -2) /* timeout */
+ if (r == -2) {
+ /* timeout */
+ if (timeout)
+ *timeout = 1;
return lastchar = EOF;
+ }
if (r == 1)
break;
if (r == 0) {
@@ -733,7 +740,7 @@ getbyte(int keytmout)
mod_export ZLE_INT_T
getfullchar(int keytmout)
{
- int inchar = getbyte(keytmout);
+ int inchar = getbyte(keytmout, NULL);
#ifdef ZLE_UNICODE_SUPPORT
return getrestchar(inchar);
@@ -759,7 +766,7 @@ getrestchar(int inchar)
/* char cnull = '\0'; */
char c = inchar;
wchar_t outchar;
- int ret;
+ int ret, timeout;
static mbstate_t ps;
/*
@@ -769,8 +776,11 @@ getrestchar(int inchar)
*/
lastchar_wide_valid = 1;
- if (inchar == EOF)
+ if (inchar == EOF) {
+ /* End of input, so reset the shift state. */
+ memset(&ps, 0, sizeof(ps));
return lastchar_wide = WEOF;
+ }
/*
* Return may be zero if we have a NULL; handle this like
@@ -781,15 +791,34 @@ getrestchar(int inchar)
/*
* Invalid input. Hmm, what's the right thing to do here?
*/
+ memset(&ps, 0, sizeof(ps));
return lastchar_wide = WEOF;
}
- /* No timeout here as we really need the character. */
- inchar = getbyte(0);
+ /*
+ * Always apply KEYTIMEOUT to the remains of the input
+ * character. The parts of a multibyte character should
+ * arrive together. If we don't do this the input can
+ * get stuck if an invalid byte sequence arrives.
+ */
+ inchar = getbyte(1, &timeout);
/* getbyte deliberately resets lastchar_wide_valid */
lastchar_wide_valid = 1;
- if (inchar == EOF)
- return lastchar_wide = WEOF;
+ if (inchar == EOF) {
+ memset(&ps, 0, sizeof(ps));
+ if (timeout)
+ {
+ /*
+ * This case means that we got a valid initial byte
+ * (since we tested for EOF above), but the followup
+ * timed out. This probably indicates a duff character.
+ * Return a '?'.
+ */
+ lastchar_wide = L'?';
+ }
+ else
+ return lastchar_wide = WEOF;
+ }
c = inchar;
}
return lastchar_wide = (ZLE_INT_T)outchar;
diff --git a/Src/Zle/zle_misc.c b/Src/Zle/zle_misc.c
index 6b79f431c..05a780b0c 100644
--- a/Src/Zle/zle_misc.c
+++ b/Src/Zle/zle_misc.c
@@ -595,7 +595,7 @@ universalargument(char **args)
*
* Hence for now this remains byte-by-byte.
*/
- while ((gotk = getbyte(0)) != EOF) {
+ while ((gotk = getbyte(0, NULL)) != EOF) {
if (gotk == '-' && !digcnt) {
minus = -1;
digcnt++;
diff --git a/Src/Zle/zle_vi.c b/Src/Zle/zle_vi.c
index a83f0197e..cb072cdb6 100644
--- a/Src/Zle/zle_vi.c
+++ b/Src/Zle/zle_vi.c
@@ -108,7 +108,7 @@ vigetkey(void)
char m[3], *str;
Thingy cmd;
- if(getbyte(0) == EOF)
+ if (getbyte(0, NULL) == EOF)
return ZLEEOF;
m[0] = lastchar;
diff --git a/Src/builtin.c b/Src/builtin.c
index 2df342533..f9ba4af3e 100644
--- a/Src/builtin.c
+++ b/Src/builtin.c
@@ -4539,7 +4539,7 @@ bin_read(char *name, char **args, Options ops, UNUSED(int func))
do {
if (izle) {
- if ((val = getkeyptr(0)) < 0)
+ if ((val = getkeyptr(0, NULL)) < 0)
break;
*bptr++ = (char) val;
nchars--;
@@ -4595,7 +4595,7 @@ bin_read(char *name, char **args, Options ops, UNUSED(int func))
/* get, and store, reply */
if (izle) {
- int key = getkeyptr(0);
+ int key = getkeyptr(0, NULL);
readbuf[0] = (key == 'y' ? 'y' : 'n');
} else {
@@ -4818,7 +4818,7 @@ zread(int izle, int *readchar)
int ret;
if (izle) {
- int c = getkeyptr(0);
+ int c = getkeyptr(0, NULL);
return (c < 0 ? EOF : c);
}
diff --git a/Src/init.c b/Src/init.c
index cd20c2237..6d78e5a1a 100644
--- a/Src/init.c
+++ b/Src/init.c
@@ -82,7 +82,7 @@ mod_export int hasam, hasxn;
/* Pointer to read-key function from zle */
/**/
-mod_export int (*getkeyptr) _((int));
+mod_export int (*getkeyptr) _((int, int *));
/* SIGCHLD mask */