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.c65
1 files changed, 40 insertions, 25 deletions
diff --git a/Src/Zle/zle_keymap.c b/Src/Zle/zle_keymap.c
index 7504ed809..28bc96b64 100644
--- a/Src/Zle/zle_keymap.c
+++ b/Src/Zle/zle_keymap.c
@@ -98,7 +98,7 @@ struct bindstate {
 /* currently selected keymap, and its name */
 
 /**/
-Keymap curkeymap;
+Keymap curkeymap, localkeymap;
 /**/
 char *curkeymapname;
 
@@ -216,7 +216,7 @@ freekeynode(HashNode hn)
 static HashTable copyto;
 
 /**/
-static Keymap
+Keymap
 newkeymap(Keymap tocopy, char *kmname)
 {
     Keymap km = zcalloc(sizeof(*km));
@@ -250,7 +250,7 @@ scancopykeys(HashNode hn, int flags)
 }
 
 /**/
-static void
+void
 deletekeymap(Keymap km)
 {
     int i;
@@ -322,21 +322,21 @@ openkeymap(char *name)
 }
 
 /**/
-static int
-unlinkkeymap(char *name)
+int
+unlinkkeymap(char *name, int ignm)
 {
     KeymapName n = (KeymapName) keymapnamtab->getnode(keymapnamtab, name);
     if(!n)
 	return 2;
-    if(n->flags & KMN_IMMORTAL)
+    if(!ignm && (n->flags & KMN_IMMORTAL))
 	return 1;
     keymapnamtab->freenode(keymapnamtab->removenode(keymapnamtab, name));
     return 0;
 }
 
 /**/
-static int
-linkkeymap(Keymap km, char *name)
+int
+linkkeymap(Keymap km, char *name, int imm)
 {
     KeymapName n = (KeymapName) keymapnamtab->getnode(keymapnamtab, name);
     if(n) {
@@ -347,9 +347,12 @@ linkkeymap(Keymap km, char *name)
 	if(!--n->keymap->rc)
 	    deletekeymap(n->keymap);
 	n->keymap = km;
-    } else
-	keymapnamtab->addnode(keymapnamtab, ztrdup(name),
-	    makekeymapnamnode(km));
+    } else {
+	n = makekeymapnamnode(km);
+	if (imm)
+	    n->flags |= KMN_IMMORTAL;
+	keymapnamtab->addnode(keymapnamtab, ztrdup(name), n);
+    }
     km->rc++;
     return 0;
 }
@@ -379,6 +382,15 @@ selectkeymap(char *name, int fb)
     return 0;
 }
 
+/* Select a local key map. */
+
+/**/
+void
+selectlocalmap(Keymap m)
+{
+    localkeymap = m;
+}
+
 /* Reopen the currently selected keymap, in case it got deleted.  This *
  * should be called after doing anything that might have run an        *
  * arbitrary user-specified command.                                   */
@@ -642,7 +654,7 @@ bin_bindkey(char *name, char **argv, char *ops, int func)
 	    return 1;
 	}
 	if(ops['e'] || ops['v'])
-	    linkkeymap(km, "main");
+	    linkkeymap(km, "main", 0);
     } else {
 	kmname = NULL;
 	km = NULL;
@@ -715,7 +727,7 @@ bin_bindkey_del(char *name, char *kmname, Keymap km, char **argv, char *ops, cha
     int ret = 0;
 
     do {
-	int r = unlinkkeymap(*argv);
+	int r = unlinkkeymap(*argv, 0);
 	if(r == 1)
 	    zwarnnam(name, "keymap name `%s' is protected", *argv, 0);
 	else if(r == 2)
@@ -735,7 +747,7 @@ bin_bindkey_link(char *name, char *kmname, Keymap km, char **argv, char *ops, ch
     if(!km) {
 	zwarnnam(name, "no such keymap `%s'", argv[0], 0);
 	return 1;
-    } else if(linkkeymap(km, argv[1])) {
+    } else if(linkkeymap(km, argv[1], 0)) {
 	zwarnnam(name, "keymap name `%s' is protected", argv[1], 0);
 	return 1;
     }
@@ -762,7 +774,7 @@ bin_bindkey_new(char *name, char *kmname, Keymap km, char **argv, char *ops, cha
 	}
     } else
 	km = NULL;
-    linkkeymap(newkeymap(km, argv[0]), argv[0]);
+    linkkeymap(newkeymap(km, argv[0]), argv[0], 0);
     return 0;
 }
 
@@ -1108,20 +1120,18 @@ default_bindings(void)
      * 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.                                         */
-    linkkeymap(vmap, "viins");
-    linkkeymap(emap, "emacs");
-    linkkeymap(amap, "vicmd");
-    linkkeymap(smap, ".safe");
+    linkkeymap(vmap, "viins", 0);
+    linkkeymap(emap, "emacs", 0);
+    linkkeymap(amap, "vicmd", 0);
+    linkkeymap(smap, ".safe", 1);
     if (((ed = zgetenv("VISUAL")) && strstr(ed, "vi")) ||
 	((ed = zgetenv("EDITOR")) && strstr(ed, "vi")))
-	linkkeymap(vmap, "main");
+	linkkeymap(vmap, "main", 0);
     else
-	linkkeymap(emap, "main");
+	linkkeymap(emap, "main", 0);
 
     /* the .safe map cannot be modified or deleted */
     smap->flags |= KM_IMMUTABLE;
-    ((KeymapName) keymapnamtab->getnode(keymapnamtab, ".safe"))->flags
-	|= KMN_IMMORTAL;
 }
 
 /*************************/
@@ -1142,7 +1152,12 @@ getkeymapcmd(Keymap km, Thingy *funcp, char **strp)
     keybuf[0] = 0;
     while((c = getkeybuf(!!lastlen)) != EOF) {
 	char *s;
-	Thingy f = keybind(km, keybuf, &s);
+	Thingy f;
+	int loc = 1;
+
+	if (!localkeymap ||
+	    (f = keybind(localkeymap, keybuf, &s)) == t_undefinedkey)
+	    loc = 0, f = keybind(km, keybuf, &s);
 
 	if(f != t_undefinedkey) {
 	    lastlen = keybuflen;
@@ -1150,7 +1165,7 @@ getkeymapcmd(Keymap km, Thingy *funcp, char **strp)
 	    str = s;
 	    lastc = c;
 	}
-	if(!keyisprefix(km, keybuf))
+	if(!keyisprefix((loc ? localkeymap : km), keybuf))
 	    break;
     }
     if(!lastlen && keybuflen)