about summary refs log tree commit diff
path: root/Src/Zle/zle_keymap.c
diff options
context:
space:
mode:
Diffstat (limited to 'Src/Zle/zle_keymap.c')
-rw-r--r--Src/Zle/zle_keymap.c64
1 files changed, 41 insertions, 23 deletions
diff --git a/Src/Zle/zle_keymap.c b/Src/Zle/zle_keymap.c
index d90838f03..5012917f5 100644
--- a/Src/Zle/zle_keymap.c
+++ b/Src/Zle/zle_keymap.c
@@ -404,7 +404,7 @@ static void
 scankeys(HashNode hn, UNUSED(int flags))
 {
     Key k = (Key) hn;
-    int f = k->nam[0] == Meta ? STOUC(k->nam[1])^32 : STOUC(k->nam[0]);
+    int f = k->nam[0] == Meta ? (unsigned char) k->nam[1]^32 : (unsigned char) k->nam[0];
     char m[3];
 
     while(skm_last < f) {
@@ -566,7 +566,7 @@ mod_export int
 bindkey(Keymap km, const char *seq, Thingy bind, char *str)
 {
     Key k;
-    int f = seq[0] == Meta ? STOUC(seq[1])^32 : STOUC(seq[0]);
+    int f = seq[0] == Meta ? (unsigned char) seq[1]^32 : (unsigned char) seq[0];
     char *buf, *ptr;
 
     if(km->flags & KM_IMMUTABLE)
@@ -661,7 +661,7 @@ keybind(Keymap km, char *seq, char **strp)
     Key k;
 
     if(ztrlen(seq) == 1) {
-	int f = seq[0] == Meta ? STOUC(seq[1])^32 : STOUC(seq[0]);
+	int f = seq[0] == Meta ? (unsigned char) seq[1]^32 : (unsigned char) seq[0];
 	Thingy bind = km->first[f];
 
 	if(bind)
@@ -687,7 +687,7 @@ keyisprefix(Keymap km, char *seq)
     if(!*seq)
 	return 1;
     if(ztrlen(seq) == 1) {
-	int f = seq[0] == Meta ? STOUC(seq[1])^32 : STOUC(seq[0]);
+	int f = seq[0] == Meta ? (unsigned char) seq[1]^32 : (unsigned char) seq[0];
 
 	if(km->first[f])
 	    return 0;
@@ -745,7 +745,7 @@ bin_bindkey(char *name, char **argv, Options ops, UNUSED(int func))
     static struct opn {
 	char o;
 	char selp;
-	int (*func) _((char *, char *, Keymap, char **, Options, char));
+	int (*func) (char *, char *, Keymap, char **, Options, char);
 	int min, max;
     } const opns[] = {
 	{ 'l', 0, bin_bindkey_lsmaps, 0,  -1 },
@@ -764,10 +764,10 @@ bin_bindkey(char *name, char **argv, Options ops, UNUSED(int func))
     int n;
 
     /* select operation and ensure no clashing arguments */
-    for(op = opns; op->o && !OPT_ISSET(ops,STOUC(op->o)); op++) ;
+    for(op = opns; op->o && !OPT_ISSET(ops,(unsigned char) op->o); op++) ;
     if(op->o)
 	for(opp = op; (++opp)->o; )
-	    if(OPT_ISSET(ops,STOUC(opp->o))) {
+	    if(OPT_ISSET(ops,(unsigned char) opp->o)) {
 		zwarnnam(name, "incompatible operation selection options");
 		return 1;
 	    }
@@ -1049,7 +1049,7 @@ bin_bindkey_bind(char *name, char *kmname, Keymap km, char **argv, Options ops,
 	    char m[3];
 
 	    if(len < 2 || len > 2 + (bseq[1] == '-') ||
-	       (first = STOUC(bseq[0])) > (last = STOUC(bseq[len - 1]))) {
+	       (first = (unsigned char) bseq[0]) > (last = (unsigned char) bseq[len - 1])) {
 		zwarnnam(name, "malformed key range `%s'", useq);
 		ret = 1;
 	    } else {
@@ -1149,8 +1149,8 @@ scanbindlist(char *seq, Thingy bind, char *str, void *magic)
     if(bind == bs->bind && (bind || !strcmp(str, bs->str)) &&
        ztrlen(seq) == 1 && ztrlen(bs->lastseq) == 1) {
 	int l = bs->lastseq[1] ?
-	    STOUC(bs->lastseq[1]) ^ 32 : STOUC(bs->lastseq[0]);
-	int t = seq[1] ? STOUC(seq[1]) ^ 32 : STOUC(seq[0]);
+	    (unsigned char) bs->lastseq[1] ^ 32 : (unsigned char) bs->lastseq[0];
+	int t = seq[1] ? (unsigned char) seq[1] ^ 32 : (unsigned char) seq[0];
 
 	if(t == l + 1) {
 	    zsfree(bs->lastseq);
@@ -1315,7 +1315,7 @@ default_bindings(void)
     Keymap vismap = newkeymap(NULL, "visual");
     Keymap smap = newkeymap(NULL, ".safe");
     Keymap vimaps[2], vilmaps[2], kptr;
-    char buf[3], *ed;
+    char buf[3];
     int i;
 
     /* vi insert mode and emacs mode:  *
@@ -1445,20 +1445,14 @@ default_bindings(void)
 	}
 
     /* Put the keymaps in the right namespace.  The "main" keymap  *
-     * will be linked to the "emacs" keymap, except that if VISUAL *
-     * or EDITOR contain the string "vi" then it will be linked to *
-     * the "viins" keymap.                                         */
+     * will be linked to the "emacs" keymap.                       */
     linkkeymap(vmap, "viins", 0);
     linkkeymap(emap, "emacs", 0);
     linkkeymap(amap, "vicmd", 0);
     linkkeymap(oppmap, "viopp", 0);
     linkkeymap(vismap, "visual", 0);
     linkkeymap(smap, ".safe", 1);
-    if (((ed = zgetenv("VISUAL")) && strstr(ed, "vi")) ||
-	((ed = zgetenv("EDITOR")) && strstr(ed, "vi")))
-	linkkeymap(vmap, "main", 0);
-    else
-	linkkeymap(emap, "main", 0);
+    linkkeymap(emap, "main", 0);
 
     /* the .safe map cannot be modified or deleted */
     smap->flags |= KM_IMMUTABLE;
@@ -1526,10 +1520,10 @@ getrestchar_keybuf(void)
      */
     while (1) {
 	if (bufind < buflen) {
-	    c = STOUC(keybuf[bufind++]);
+	    c = (unsigned char) keybuf[bufind++];
 	    if (c == Meta) {
 		DPUTS(bufind == buflen, "Meta at end of keybuf");
-		c = STOUC(keybuf[bufind++]) ^ 32;
+		c = (unsigned char) keybuf[bufind++] ^ 32;
 	    }
 	} else {
 	    /*
@@ -1586,7 +1580,7 @@ getkeymapcmd(Keymap km, Thingy *funcp, char **strp)
     Thingy func = t_undefinedkey;
     char *str = NULL;
     int lastlen = 0, lastc = lastchar;
-    int timeout = 0;
+    int timeout = 0, csi = 0;
 
     keybuflen = 0;
     keybuf[0] = 0;
@@ -1636,7 +1630,31 @@ getkeymapcmd(Keymap km, Thingy *funcp, char **strp)
 	    }
 #endif
 	}
-	if (!ispfx)
+
+	/* CSI key sequences have a well defined structure so if we currently
+	 * have an incomplete one, loop so the rest of it will be included in
+	 * the key sequence if that arrives within the timeout. */
+	if (!csi && keybuflen >= 3 && keybuf[keybuflen - 3] == '\033' &&
+		keybuf[keybuflen - 2] == '[')
+	    csi = keybuflen - 1;
+	if (csi) {
+	    if (keybuf[keybuflen - 2] == Meta || keybuf[keybuflen - 1] < 0x20
+		   || keybuf[keybuflen - 1] > 0x3f) {
+	    /* If we reach the end of a valid CSI sequence and the matched key
+	     * binding is for part of the CSI introduction, select instead the
+	     * undefined-key widget and consume the full sequence from the
+	     * input buffer. */
+		if (keybuf[keybuflen - 1] >= 0x40 &&
+			keybuf[keybuflen - 1] <= 0x7e && lastlen > csi - 2 &&
+			lastlen <= csi) {
+		    func = t_undefinedkey;
+		    lastlen = keybuflen;
+		}
+		csi = 0;
+	    }
+	}
+
+	if (!ispfx && !csi)
 	    break;
     }
     if(!lastlen && keybuflen)