zsh-workers
 help / color / mirror / code / Atom feed
* PATCH: local keymaps
@ 1999-06-23  7:50 Sven Wischnowsky
  1999-06-23  7:46 ` Peter Stephenson
                   ` (4 more replies)
  0 siblings, 5 replies; 8+ messages in thread
From: Sven Wischnowsky @ 1999-06-23  7:50 UTC (permalink / raw)
  To: zsh-workers


This allows one to set a local keymap that (partly) overrides the
current keymap. It is done by defining such a keymap, doing some
binkey()s in it and then install it with selectlocalmap(map). When it
isn't used any more selectlocalmap(NULL) de-installs the local map.

Currently this is only used for complist, which uses a local map with
bindings for \t, \r, \n, and the default cursor key sequences. But the
keymap is user-visible (named `menuselect' -- jusging from the names
of the builtin keymaps I probably should have named it `menusel' but I 
didn't feel like that), and can be modified using `bindkey'.

Maybe we should define other local keymaps for execute-named-command,
the incremental search functions, and so on (probably leaving them
empty by default).


Bye
 Sven

P.S.: Most of this patch is changing calls to (|un)linkkeymap() which
      I have given new arguments.
P.P.S.: I you have trouble applying this patch it's because it patches 
        files named *complist* instead of *collist*.

diff -u oos/Zle/complist.c Src/Zle/complist.c
--- oos/Zle/complist.c	Wed Jun 23 09:19:34 1999
+++ Src/Zle/complist.c	Wed Jun 23 09:19:04 1999
@@ -31,6 +31,7 @@
 #include "complist.pro"
 
 static Widget w_menuselect;
+static Keymap mskeymap;
 
 /* We use the parameters ZLS_COLORS and ZLS_COLOURS in the same way as
  * the color ls does. It's just that we don't support the `or' file
@@ -629,6 +630,7 @@
     if (getcols(NULL) || (dummy && !getsparam("ZLS_SELECT")))
 	return 1;
 
+    selectlocalmap(mskeymap);
     noselect = 0;
     mselect = (*(minfo.cur))->gnum;
     for (;;) {
@@ -813,6 +815,7 @@
 	do_single(**p);
 	mselect = (**p)->gnum;
     }
+    selectlocalmap(NULL);
     mselect = -1;
     inselect = 0;
     if (!noselect) {
@@ -866,6 +869,19 @@
     }
     addhookfunc("list_matches", (Hookfn) complistmatches);
     addhookfunc("menu_start", (Hookfn) domenuselect);
+    mskeymap = newkeymap(NULL, "menuselect");
+    linkkeymap(mskeymap, "menuselect", 1);
+    bindkey(mskeymap, "\t", refthingy(t_completeword), NULL);
+    bindkey(mskeymap, "\n", refthingy(t_acceptline), NULL);
+    bindkey(mskeymap, "\r", refthingy(t_acceptline), NULL);
+    bindkey(mskeymap, "\33[A",  refthingy(t_uplineorhistory), NULL);
+    bindkey(mskeymap, "\33[B",  refthingy(t_downlineorhistory), NULL);
+    bindkey(mskeymap, "\33[C",  refthingy(t_forwardchar), NULL);
+    bindkey(mskeymap, "\33[D",  refthingy(t_backwardchar), NULL);
+    bindkey(mskeymap, "\33OA",  refthingy(t_uplineorhistory), NULL);
+    bindkey(mskeymap, "\33OB",  refthingy(t_downlineorhistory), NULL);
+    bindkey(mskeymap, "\33OC",  refthingy(t_forwardchar), NULL);
+    bindkey(mskeymap, "\33OD",  refthingy(t_backwardchar), NULL);
     return 0;
 }
 
@@ -881,6 +897,7 @@
     deletezlefunction(w_menuselect);
     deletehookfunc("list_matches", (Hookfn) complistmatches);
     deletehookfunc("menu_start", (Hookfn) domenuselect);
+    unlinkkeymap("menuselect", 1);
     return 0;
 }
 
diff -u oos/Zle/zle_keymap.c Src/Zle/zle_keymap.c
--- oos/Zle/zle_keymap.c	Tue Jun 22 15:31:36 1999
+++ Src/Zle/zle_keymap.c	Wed Jun 23 09:02:56 1999
@@ -98,7 +98,7 @@
 /* currently selected keymap, and its name */
 
 /**/
-Keymap curkeymap;
+Keymap curkeymap, localkeymap;
 /**/
 char *curkeymapname;
 
@@ -216,7 +216,7 @@
 static HashTable copyto;
 
 /**/
-static Keymap
+Keymap
 newkeymap(Keymap tocopy, char *kmname)
 {
     Keymap km = zcalloc(sizeof(*km));
@@ -250,7 +250,7 @@
 }
 
 /**/
-static void
+void
 deletekeymap(Keymap km)
 {
     int i;
@@ -322,21 +322,21 @@
 }
 
 /**/
-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 @@
 	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 @@
     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 @@
 	    return 1;
 	}
 	if(ops['e'] || ops['v'])
-	    linkkeymap(km, "main");
+	    linkkeymap(km, "main", 0);
     } else {
 	kmname = NULL;
 	km = NULL;
@@ -715,7 +727,7 @@
     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 @@
     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 @@
 	}
     } else
 	km = NULL;
-    linkkeymap(newkeymap(km, argv[0]), argv[0]);
+    linkkeymap(newkeymap(km, argv[0]), argv[0], 0);
     return 0;
 }
 
@@ -1108,20 +1120,18 @@
      * 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 @@
     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 @@
 	    str = s;
 	    lastc = c;
 	}
-	if(!keyisprefix(km, keybuf))
+	if(!keyisprefix((loc ? localkeymap : km), keybuf))
 	    break;
     }
     if(!lastlen && keybuflen)
diff -u oos/Zle/zle_main.c Src/Zle/zle_main.c
--- oos/Zle/zle_main.c	Tue Jun 22 15:31:37 1999
+++ Src/Zle/zle_main.c	Wed Jun 23 09:02:57 1999
@@ -507,6 +507,7 @@
 	viinsbegin = 0;
 	statusline = NULL;
 	selectkeymap("main", 1);
+	selectlocalmap(NULL);
 	fixsuffix();
 	if ((s = (unsigned char *)getlinknode(bufstack))) {
 	    setline((char *)s);
@@ -542,6 +543,7 @@
 	    statusline = NULL;
 	    vilinerange = 0;
 	    reselectkeymap();
+	    selectlocalmap(NULL);
 	    bindk = getkeycmd();
 	    if (!ll && isfirstln && c == eofchar) {
 		eofsent = 1;
diff -u ood/Zsh/mod_complist.yo Doc/Zsh/mod_complist.yo
--- ood/Zsh/mod_complist.yo	Tue Jun 22 15:31:43 1999
+++ Doc/Zsh/mod_complist.yo	Wed Jun 23 09:02:57 1999
@@ -102,3 +102,14 @@
 match be inserted and the tt(redisplay) and tt(clear-screen) functions 
 work as usual without leaving menu-selection. Any other zle function
 leaves menu-selection and makes that function be executed.
+
+During this selection the widget uses the keymap tt(menuselect). Any
+key that is not defined in this keymap or that is bound to
+tt(undefined-key) is looked up in the keymap currently selected. This
+is used to ensure that the most important keys used during selection
+have sensible default (namely the cursor keys, return, and TAB). But
+the tt(menuselect) is user-visible and other keys can be defined in it 
+using the tt(bindkey) builtin command (see
+ifzman(zmanref(zshmodules))\
+ifnzman(noderef(The zle Module))\
+).

--
Sven Wischnowsky                         wischnow@informatik.hu-berlin.de


^ permalink raw reply	[flat|nested] 8+ messages in thread
* RE: PATCH: local keymaps
@ 1999-06-23  9:53 Sven Wischnowsky
  1999-06-24 15:29 ` Bart Schaefer
  0 siblings, 1 reply; 8+ messages in thread
From: Sven Wischnowsky @ 1999-06-23  9:53 UTC (permalink / raw)
  To: zsh-workers


Andrej Borsenkow wrote:

> Local keymaps imply the ability to switch between keymaps (well, it was
> internally always there). That returns us to the old question - is it possible
> to siwtch keymap on-the-fly? Curently, it seems, that
> 
> bindkey -A viins main
> 
> will change your keymap from emacs to vi. Is it the correct way? Unforunately,
> after
> 
> bindkey -A vicmd main
> 
> no more input is possible. I would expect, that at least `a' would bring me back
> to viins.

For the builtin ones there are -e, -v, and -a (the last one uses
vicmd, but does not link it to main -- as the others do). For
user-defined keymaps this is the intended way, I think.

About switching keymaps using local maps: this is probably a bit of a
misnomer if we think about emacs. They are really override-maps, with
the main keymap still shining through the holes (the holes are where
undefined-key is bound).
But there is one place where I would like local keymaps to be usable:
an option to vared to select such a override-map during editing (and
remove it afterwards).

> May be, it's time to allow for binding of generic keys instead of just escape
> sequences. E.g. in vim (or elvis) you can map charaters Right, Left, Home, F1
> etc. Let's be more user friendly :-) Zsh already has access to termcap/terminfo,
> so it is little overhead - but it at least will make startup files much much
> simpler (assuming, that you work under more than one terminal type)

Yes, I was wishing we had this when adding the keymap to complist (we
would need an option for this to bindkey, though, because `bindkey Up' 
currently binds the two-character sequence `U' `p').

Now, where are our termcap/info experts?

Bye
 Sven


--
Sven Wischnowsky                         wischnow@informatik.hu-berlin.de


^ permalink raw reply	[flat|nested] 8+ messages in thread

end of thread, other threads:[~1999-06-24 15:31 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
1999-06-23  7:50 PATCH: local keymaps Sven Wischnowsky
1999-06-23  7:46 ` Peter Stephenson
1999-06-23  7:59 ` Andrej Borsenkow
1999-06-23  8:00 ` Andrej Borsenkow
1999-06-23  8:07 ` Meta key binding " Andrej Borsenkow
1999-06-23  8:49 ` Cannot build Zsh after this patch " Andrej Borsenkow
1999-06-23  9:53 Sven Wischnowsky
1999-06-24 15:29 ` Bart Schaefer

Code repositories for project(s) associated with this public inbox

	https://git.vuxu.org/mirror/zsh/

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).