Zsh Mailing List Archive
Messages sorted by: Reverse Date, Date, Thread, Author

PATCH: use viopp and visual keymaps

I'm breaking this up into several patches to make it easy to discuss
different aspects. I'll try not to break future git bisects in the
process of doing all the git rebase stuff. For the impatient, I
think much of my working is on git.code.sf.net/u/opk/zsh.

To begin with, this adds support for two new keymaps: visual and viopp.
They are used as local keymaps above vicmd.

visual is for when the region is active in vi command mode.
viopp is for operator pending so, for example if you do d$, a viopp
binding of $ will override the one in vicmd.

The use of local keymaps preserves backward compatibility nicely.
We don't currently use them anywhere with vicmd so no need more multiple
layers just yet. All existing user key bindings will continue to work in
all three situations. This will incur the nuisance of having to bind
text objects for both visual and viopp, however. This is also the thing
that drove my recent change to local keymap hiding rules: i and a are
bound in vicmd but shouldn't hide iw etc in visual/vicmd.

Currently, this leaves it up to the user to create the two keymaps. This
will probably change. For now, the following is about all you can do:

  bindkey -N viopp
  bindkey -N visual
  bindkey -M visual 'o' exchange-point-and-mark
  bindkey -M viopp '\e' vi-cmd-mode # escape should cancel a delete/change etc

I'll consider default configuration and bindings much later. That'll be
the part that most affects compatibility for vi purists verses making
stuff work out-of-the-box for vim experts.


diff --git a/Src/Zle/zle_main.c b/Src/Zle/zle_main.c
index 8344c66..d157e36 100644
--- a/Src/Zle/zle_main.c
+++ b/Src/Zle/zle_main.c
@@ -1067,6 +1067,7 @@ getrestchar(int inchar)
+    Keymap km;
 #if !defined(HAVE_POLL) && defined(HAVE_SELECT)
     struct timeval tv;
     fd_set foofd;
@@ -1088,8 +1089,10 @@ zlecore(void)
 	statusline = NULL;
 	vilinerange = 0;
-	selectlocalmap(NULL);
+	selectlocalmap(invicmdmode() && region_active && (km = openkeymap("visual"))
+	    ? km : NULL);
 	bindk = getkeycmd();
+	selectlocalmap(NULL);
 	if (bindk) {
 	    if (!zlell && isfirstln && !(zlereadflags & ZLRF_IGNOREEOF) &&
 		lastchar == eofchar) {
diff --git a/Src/Zle/zle_vi.c b/Src/Zle/zle_vi.c
index d74b40d..89fa685 100644
--- a/Src/Zle/zle_vi.c
+++ b/Src/Zle/zle_vi.c
@@ -167,6 +167,10 @@ getvirange(int wf)
     virangeflag = 1;
     wordflag = wf;
+    /* use operator-pending keymap if one exists */
+    Keymap km = openkeymap("viopp");
+    if (km)
+	selectlocalmap(km);
     /* Now we need to execute the movement command, to see where it *
      * actually goes.  virangeflag here indicates to the movement   *
      * function that it should place the cursor at the end of the   *
@@ -203,6 +207,7 @@ getvirange(int wf)
     } while(prefixflag && !ret);
     wordflag = 0;
     virangeflag = 0;
+    selectlocalmap(NULL);
     /* It is an error to use a non-movement command to delimit the *
      * range.  We here reject the case where the command modified  *

Messages sorted by: Reverse Date, Date, Thread, Author