zsh-workers
 help / color / mirror / code / Atom feed
* PATCH: key bindings, fixes, docs, tests for vi stuff
@ 2014-11-17 21:36 Oliver Kiddle
  2014-11-18  8:04 ` Jun T.
  0 siblings, 1 reply; 28+ messages in thread
From: Oliver Kiddle @ 2014-11-17 21:36 UTC (permalink / raw)
  To: Zsh workers

With this patch, the viopp and visual keymaps are now created by default
with a few keys bound. The patch adds documentation and tests. For
Solaris, I needed to add another stty parameter because it was turning
tabs into spaces. Perhaps I should change the way it prints the buffer
to be fully quoted ($'...' style).

There's also a couple of minor fixes and, as I mentioned before, the
vi-delete/vi-backward-delete changes are backed out as the binding of x
in visual does the same job.

Oliver

diff --git a/Doc/Zsh/zle.yo b/Doc/Zsh/zle.yo
index 998bf4a..aa7ff4b 100644
--- a/Doc/Zsh/zle.yo
+++ b/Doc/Zsh/zle.yo
@@ -60,12 +60,14 @@ or more names.  If all of a keymap's names are deleted, it disappears.
 findex(bindkey, use of)
 tt(bindkey) can be used to manipulate keymap names.
 
-Initially, there are six keymaps:
+Initially, there are eight keymaps:
 
 startsitem()
 sitem(tt(emacs))(EMACS emulation)
 sitem(tt(viins))(vi emulation - insert mode)
 sitem(tt(vicmd))(vi emulation - command mode)
+sitem(tt(viopp))(vi emulation - operator pending)
+sitem(tt(visual))(vi emulation - selection active)
 sitem(tt(isearch))(incremental search mode)
 sitem(tt(command))(read a command name)
 sitem(tt(.safe))(fallback keymap)
@@ -122,6 +124,21 @@ in user-defined widgets with the tt(read-command) widget, described
 ifzman(below)\
 ifnzman(in noderef(Miscellaneous) below)\
 .
+subsect(Local Keymaps)
+cindex(local keymaps)
+While for normal editing a single keymap is used exclusively, in many
+modes a local keymap allows for some keys to be customised. For example,
+in an incremental search mode, a binding in the tt(isearch) keymap will
+override a binding in the tt(main) keymap but all keys that are not
+overriden can still be used.
+
+If a key sequence is defined in a local keymap, it will hide a key
+sequence in the global keymap that is a prefix of that sequence. An
+example of this occurs with the binding of tt(iw) in tt(viopp) as this
+hides the binding of tt(i) in tt(vicmd). However, a longer sequence in
+the global keymap that shares the same prefix can still apply so for
+example the binding of tt(^Xa) in the global keymap will be unaffected
+by the binding of tt(^Xb) in the local keymap.
 
 texinode(Zle Builtins)(Zle Widgets)(Keymaps)(Zsh Line Editor)
 sect(Zle Builtins)
@@ -817,7 +834,10 @@ cursor remains between the new tt($LBUFFER) and the old tt($RBUFFER).
 )
 vindex(MARK)
 item(tt(MARK) (integer))(
-Like tt(CURSOR), but for the mark.
+Like tt(CURSOR), but for the mark. With vi-mode operators that wait for
+a movement command to select a region of text, setting tt(MARK) allows
+the selection to extend in both directions from the the initial cursor
+position.
 )
 vindex(NUMERIC)
 item(tt(NUMERIC) (integer))(
@@ -863,7 +883,9 @@ cursor remains between the old tt($LBUFFER) and the new tt($RBUFFER).
 vindex(REGION_ACTIVE)
 item(tt(REGION_ACTIVE) (integer))(
 Indicates if the region is currently active.  It can be assigned 0 or 1
-to deactivate and activate the region respectively;
+to deactivate and activate the region respectively. A value of 2
+activates the region in line-wise mode with the highlighted text
+extending for whole lines only;
 ifzman(see em(Character Highlighting) below)\
 ifnzman(noderef(Character Highlighting)).
 )
@@ -2275,6 +2297,16 @@ item(tt(vi-undo-change) (unbound) (u) (unbound))(
 Undo the last text modification.
 If repeated, redo the modification.
 )
+tindex(visual-mode)
+item(tt(visual-mode) (unbound) (v) (unbound))(
+Toggle vim-style visual selection mode. If line-wise visual mode is
+currently enabled then it is changed to being character-wise.
+)
+tindex(visual-line-mode)
+item(tt(visual-line-mode) (unbound) (V) (unbound))(
+Toggle vim-style line-wise visual selection mode. If character-wise
+visual mode is currently enabled then it is changed to being line-wise.
+)
 tindex(what-cursor-position)
 item(tt(what-cursor-position) (^X=) (unbound) (unbound))(
 Print the character under the cursor, its code as an octal, decimal and
diff --git a/Src/Zle/zle_bindings.c b/Src/Zle/zle_bindings.c
index 6826913..50a2955 100644
--- a/Src/Zle/zle_bindings.c
+++ b/Src/Zle/zle_bindings.c
@@ -376,7 +376,7 @@ int vicmdbind[128] = {
     /* S */ z_vichangewholeline,
     /* T */ z_vifindprevcharskip,
     /* U */ z_undefinedkey,
-    /* V */ z_undefinedkey,
+    /* V */ z_visuallinemode,
     /* W */ z_viforwardblankword,
     /* X */ z_vibackwarddeletechar,
     /* Y */ z_viyankwholeline,
@@ -408,7 +408,7 @@ int vicmdbind[128] = {
     /* s */ z_visubstitute,
     /* t */ z_vifindnextcharskip,
     /* u */ z_viundochange,
-    /* v */ z_undefinedkey,
+    /* v */ z_visualmode,
     /* w */ z_viforwardword,
     /* x */ z_videletechar,
     /* y */ z_viyank,
diff --git a/Src/Zle/zle_keymap.c b/Src/Zle/zle_keymap.c
index 6a71076..216e302 100644
--- a/Src/Zle/zle_keymap.c
+++ b/Src/Zle/zle_keymap.c
@@ -1277,8 +1277,10 @@ default_bindings(void)
     Keymap vmap = newkeymap(NULL, "viins");
     Keymap emap = newkeymap(NULL, "emacs");
     Keymap amap = newkeymap(NULL, "vicmd");
+    Keymap oppmap = newkeymap(NULL, "viopp");
+    Keymap vismap = newkeymap(NULL, "visual");
     Keymap smap = newkeymap(NULL, ".safe");
-    Keymap vimaps[2], kptr;
+    Keymap vimaps[2], vilmaps[2], kptr;
     char buf[3], *ed;
     int i;
 
@@ -1332,6 +1334,22 @@ default_bindings(void)
 	add_cursor_key(kptr, TCLEFTCURSOR, t_vibackwardchar, 'D');
 	add_cursor_key(kptr, TCRIGHTCURSOR, t_viforwardchar, 'C');
     }
+    vilmaps[0] = oppmap;
+    vilmaps[1] = vismap;
+    for (i = 0; i < 2; i++) {
+	/* vi visual selection and operator pending local maps */
+	kptr = vilmaps[i];
+	add_cursor_key(kptr, TCUPCURSOR, t_upline, 'A');
+	add_cursor_key(kptr, TCDOWNCURSOR, t_downline, 'B');
+	bindkey(kptr, "k", refthingy(t_upline), NULL);
+	bindkey(kptr, "j", refthingy(t_downline), NULL);
+    }
+    /* escape in operator pending cancels the operation */
+    bindkey(oppmap, "\33", refthingy(t_vicmdmode), NULL);
+    bindkey(vismap, "o", refthingy(t_exchangepointandmark), NULL);
+    bindkey(vismap, "p", refthingy(t_putreplaceselection), NULL);
+    bindkey(vismap, "x", refthingy(t_videlete), NULL);
+    bindkey(vismap, "~", refthingy(t_vioperswapcase), NULL);
 
     /* emacs mode: arrow keys */ 
     add_cursor_key(emap, TCUPCURSOR, t_uplineorhistory, 'A');
@@ -1373,6 +1391,8 @@ default_bindings(void)
     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")))
diff --git a/Src/Zle/zle_refresh.c b/Src/Zle/zle_refresh.c
index f0351ad..467629d 100644
--- a/Src/Zle/zle_refresh.c
+++ b/Src/Zle/zle_refresh.c
@@ -1037,8 +1037,6 @@ zrefresh(void)
 	    region_highlights[0].start = mark;
 	    region_highlights[0].end = zlecs;
 	}
-	if (invicmdmode())
-	    INCPOS(region_highlights[0].end);
 	if (region_active == 2) {
 	    int origcs = zlecs;
 	    zlecs = region_highlights[0].end;
@@ -1046,7 +1044,8 @@ zrefresh(void)
 	    zlecs = region_highlights[0].start;
 	    region_highlights[0].start = findbol();
 	    zlecs = origcs;
-	}
+	} else if (invicmdmode())
+	    INCPOS(region_highlights[0].end);
     } else {
 	region_highlights[0].start = region_highlights[0].end = -1;
     }
diff --git a/Src/Zle/zle_vi.c b/Src/Zle/zle_vi.c
index 3a4304c..84cba77 100644
--- a/Src/Zle/zle_vi.c
+++ b/Src/Zle/zle_vi.c
@@ -258,7 +258,7 @@ getvirange(int wf)
 	pos = tmp;
     }
 
-    if (visual && invicmdmode())
+    if (visual == 1 && invicmdmode())
 	INCPOS(pos);
 
     /* Was it a line-oriented move?  If so, the command will have set *
@@ -389,9 +389,6 @@ videletechar(char **args)
 
     startvichange(-1);
 
-    if (region_active)
-	return killregion(args);
-
     /* handle negative argument */
     if (n < 0) {
 	int ret;
@@ -804,9 +801,6 @@ vibackwarddeletechar(char **args)
     if (invicmdmode())
 	startvichange(-1);
 
-    if (region_active)
-	return killregion(args);
-
     /* handle negative argument */
     if (n < 0) {
 	int ret;
diff --git a/Test/X02zlevi.ztst b/Test/X02zlevi.ztst
index 297fb9ae..94afb60 100644
--- a/Test/X02zlevi.ztst
+++ b/Test/X02zlevi.ztst
@@ -273,6 +273,115 @@
 >BUFFER: one wo
 >CURSOR: 2
 
+  zletest $'one two\evbcx'
+0:change selection
+>BUFFER: one x
+>CURSOR: 5
+
+  zletest $'four\eOthree\eOtwo\eOone\evjjhCnew'
+0:change character wise selection with C acts linewise
+>BUFFER: new
+>four
+>CURSOR: 3
+
+  zletest $'x testing\ehvbx'
+0:x kills selections
+>BUFFER: x g
+>CURSOR: 2
+
+  zletest $'one two\eyb0vep'
+0:put over selection at start of buffer
+>BUFFER: tw two
+>CURSOR: 1
+
+  zletest $'hello\C-wbye\evhp'
+0:put over selection at end of buffer
+>BUFFER: bhello
+>CURSOR: 5
+
+  zletest $'one\eotwo\eyykVp'
+0:yank linewise and put over linewise selection at start of buffer
+>BUFFER: two
+>two
+>CURSOR: 0
+
+  zletest $'one\eotwo\eothree\eyykVp'
+0:yank linewise and put over linewise selection in middle of buffer
+>BUFFER: one
+>three
+>three
+>CURSOR: 4
+
+  zletest $'two\eOone\eyyjVp'
+0:yank linewise and put over linewise selection at end of buffer
+>BUFFER: one
+>one
+>CURSOR: 4
+
+  zletest $'one\eyhVp'
+0:yank character-wise and put over linewise selection
+>BUFFER: n
+>CURSOR: 0
+
+# vim puts a blank line above in this test
+  zletest $'one\eotwo\eyy0kvlp'
+0:yank linewise and put over character-wise selection at start of buffer
+>BUFFER: two
+>e
+>two
+>CURSOR: 0
+
+  zletest $'one\eyyhvp'
+0:yank linewise and put over character-wise selection in middle of buffer
+>BUFFER: o
+>one
+>e
+>CURSOR: 2
+
+# vim behaviour on this one really looks like a bug
+  zletest $'two\eOone\eyyjvhp'
+0:yank linewise and put over character-wise selection at end of buffer
+>BUFFER: one
+>t
+>one
+>CURSOR: 6
+
+  zletest $'abc123456789\exxxxxxxxxhv"9p0P'
+0:paste last (9th) register over a selection
+>BUFFER: ba9c
+>CURSOR: 0
+
+  zletest $'one\eo\eo\eotwo\ekkVdvd'
+0:delete blank line using selection
+>BUFFER: one
+>two
+>CURSOR: 4
+
+  zletest $'One Two Three\e2bvw~'
+0:toggle case of selection
+>BUFFER: One tWO three
+>CURSOR: 4
+
+  zletest $'    ----word    ----    word    word----    ----\e42|daw30|daw22|daw14|daw2|daw'
+0:delete all word on blanks
+>BUFFER: word
+>CURSOR: 0
+
+  zletest $'    word----word    word----word    word    \e38|daw30|daw22|daw14|daw6|daw'
+0:delete all word on alphanumerics
+>BUFFER:     --------
+>CURSOR: 4
+
+  zletest $'    ----word----    ----word----    ----    \e38|daw30|daw22|daw14|daw6|daw'
+0:delete all word on other characters
+>BUFFER:     wordword
+>CURSOR: 4
+
+  zletest $'- word word\e4|2daw'
+0:delete all word with numeric argument
+>BUFFER: -
+>CURSOR: 0
+
 %clean
 
   zmodload -ui zsh/zpty
diff --git a/Test/comptest b/Test/comptest
index 654c0f1..c67237a 100644
--- a/Test/comptest
+++ b/Test/comptest
@@ -34,7 +34,7 @@ comptestinit () {
 "fpath=( $fpath )" \
 "bindkey -$comptest_keymap" \
 'LISTMAX=10000000
-stty 38400 columns 80 rows 24 werase undef
+stty 38400 columns 80 rows 24 werase undef tabs
 TERM=vt100
 KEYTIMEOUT=1
 setopt zle


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

* Re: PATCH: key bindings, fixes, docs, tests for vi stuff
  2014-11-17 21:36 PATCH: key bindings, fixes, docs, tests for vi stuff Oliver Kiddle
@ 2014-11-18  8:04 ` Jun T.
  2014-11-19  8:48   ` Oliver Kiddle
  2014-11-21  0:01   ` Oliver Kiddle
  0 siblings, 2 replies; 28+ messages in thread
From: Jun T. @ 2014-11-18  8:04 UTC (permalink / raw)
  To: zsh-workers

X02zlevi.ztst fails on Linux and Mac (and maybe on other systems):

*** 1,2 ****
! BUFFER: word
! CURSOR: 0
--- 1,2 ----
! BUFFER:     ----word    ----    word    word---- w30|daw22|daw14|daw2|daw  ----
! CURSOR: 65
Test ./X02zlevi.ztst failed: output differs from expected as shown above for:
 zletest $'    ----word    ----    word    word----    ----\e42|daw30|daw22|daw14|daw2|daw'
Was testing: delete all word on blanks


Apparently 'daw' is not working.
One or more diff hunk(s) are missing in the patch?


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

* Re: PATCH: key bindings, fixes, docs, tests for vi stuff
  2014-11-18  8:04 ` Jun T.
@ 2014-11-19  8:48   ` Oliver Kiddle
  2014-11-19 15:35     ` Ray Andrews
  2014-11-21  0:01   ` Oliver Kiddle
  1 sibling, 1 reply; 28+ messages in thread
From: Oliver Kiddle @ 2014-11-19  8:48 UTC (permalink / raw)
  To: zsh-workers; +Cc: Ray Andrews

"Jun T." wrote:
> *** 1,2 ****
> ! BUFFER: word
> ! CURSOR: 0
> --- 1,2 ----
> ! BUFFER:     ----word    ----    word    word---- w30|daw22|daw14|daw2|daw  ----
> ! CURSOR: 65
> Test ./X02zlevi.ztst failed: output differs from expected as shown above for:
>  zletest $'    ----word    ----    word    word----    ----\e42|daw30|daw22|daw14|daw2|daw'
> Was testing: delete all word on blanks

Thanks for letting me know. Sorry about this.

> Apparently 'daw' is not working.
> One or more diff hunk(s) are missing in the patch?

I must have made a mistake when resolving conflicts in a git rebase
and the tests found their way into the patch I posted. And because the
implementation of aw was in a loadable module, the tests actually passed
when I checked them: it must have picked up the module from a previous
build.

I'd prefer to leave the test in for now because I should have the
associated code in good enough shape to post before long so please be
patient for now.

Oliver


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

* Re: PATCH: key bindings, fixes, docs, tests for vi stuff
  2014-11-19  8:48   ` Oliver Kiddle
@ 2014-11-19 15:35     ` Ray Andrews
  0 siblings, 0 replies; 28+ messages in thread
From: Ray Andrews @ 2014-11-19 15:35 UTC (permalink / raw)
  To: zsh-workers

On 11/19/2014 12:48 AM, Oliver Kiddle wrote:
> I'd prefer to leave the test in for now because I should have the 
> associated code in good enough shape to post before long so please be 
> patient for now. Oliver 

Sure.  I get feeling that this isn't mission critical.  It is comforting 
to know that there is so much attention paid to testing things.


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

* Re: PATCH: key bindings, fixes, docs, tests for vi stuff
  2014-11-18  8:04 ` Jun T.
  2014-11-19  8:48   ` Oliver Kiddle
@ 2014-11-21  0:01   ` Oliver Kiddle
  2014-11-21  0:49     ` Bart Schaefer
                       ` (2 more replies)
  1 sibling, 3 replies; 28+ messages in thread
From: Oliver Kiddle @ 2014-11-21  0:01 UTC (permalink / raw)
  To: zsh-workers

On 18 Nov, "Jun T." wrote:
> Apparently 'daw' is not working.

With this patch, that test failure should now be fixed.

I'd recommend Emacs mode users at least look at the new
select-in-shell-word widget. I can imagine it might be useful.

It is bound to "ia" in the viopp and visual keymaps along with aa which
is similar.

This also adds the usual vim aw aW iw and iW bindings that can be used
together with vi operators (c d y p etc) or visual selection mode.
Vim has many more, most not useful from zsh (sentences, paragraphs etc).

The code for select-in-shell-word is based on that for the (z)
expansion. I was hoping it would shed some light on the lexer but, it
didn't really.

Oliver

diff --git a/Doc/Zsh/zle.yo b/Doc/Zsh/zle.yo
index aa7ff4b..f9dcd80 100644
--- a/Doc/Zsh/zle.yo
+++ b/Doc/Zsh/zle.yo
@@ -1975,7 +1975,7 @@ When a previous completion displayed a list below the prompt, this
 widget can be used to move the prompt below the list.
 )
 enditem()
-texinode(Miscellaneous)()(Completion)(Zle Widgets)
+texinode(Miscellaneous)(Text Objects)(Completion)(Zle Widgets)
 subsect(Miscellaneous)
 startitem()
 tindex(accept-and-hold)
@@ -2333,6 +2333,50 @@ If the last command executed was a digit as part of an argument,
 continue the argument.  Otherwise, execute vi-beginning-of-line.
 )
 enditem()
+texinode(Text Objects)()(Miscellaneous)(Zle Widgets)
+subsect(Text Objects)
+cindex(text objects)
+Text objects are commands that can be used to select a block of text
+according to some criteria. They are a feature of the vim text editor
+and so are primarily intended for use with vi operators or from visual
+selection mode. However, they can also be used from vi-insert or emacs
+mode. Key bindings listed below apply to the tt(viopp) and tt(visual)
+keymaps.
+
+startitem()
+tindex(select-a-blank-word)
+item(tt(select-a-blank-word) (aW))(
+Select a word including adjacent blanks, where a word is defined as a
+series of non-blank characters. With a numeric argument, multiple words
+will be selected.
+)
+tindex(select-a-shell-word)
+item(tt(select-a-shell-word) (aa))(
+Select the current command argument applying the normal rules for
+quoting.
+)
+tindex(select-a-word)
+item(tt(select-a-word) (aw))(
+Select a word including adjacent blanks, using the normal vi-style word
+definition. With a numeric argument, multiple words will be selected.
+)
+tindex(select-in-blank-word)
+item(tt(select-in-blank-word) (iW))(
+Select a word, where a word is defined as a series of non-blank
+characters. With a numeric argument, multiple words will be selected.
+)
+tindex(select-in-shell-word)
+item(tt(select-in-shell-word) (ia))(
+Select the current command argument applying the normal rules for
+quoting. If the argument begins and ends with matching quote characters,
+these are not included in the selection.
+)
+tindex(select-in-word)
+item(tt(select-in-word) (iw))(
+Select a word, using the normal vi-style word definition. With a numeric
+argument, multiple words will be selected.
+)
+enditem()
 
 texinode(Character Highlighting)()(Zle Widgets)(Zsh Line Editor)
 sect(Character Highlighting)
diff --git a/Src/Zle/iwidgets.list b/Src/Zle/iwidgets.list
index 2618297..1a664e5 100644
--- a/Src/Zle/iwidgets.list
+++ b/Src/Zle/iwidgets.list
@@ -100,6 +100,12 @@
 "reset-prompt", resetprompt, ZLE_MENUCMP | ZLE_KEEPSUFFIX | ZLE_LASTCOL
 "reverse-menu-complete", reversemenucomplete, ZLE_MENUCMP | ZLE_KEEPSUFFIX | ZLE_ISCOMP
 "run-help", processcmd, ZLE_MENUCMP | ZLE_KEEPSUFFIX | ZLE_LASTCOL
+"select-a-word", selectword, ZLE_KEEPSUFFIX
+"select-in-word", selectword, ZLE_KEEPSUFFIX
+"select-a-blank-word", selectword, ZLE_KEEPSUFFIX
+"select-in-blank-word", selectword, ZLE_KEEPSUFFIX
+"select-a-shell-word", selectargument, ZLE_KEEPSUFFIX
+"select-in-shell-word", selectargument, ZLE_KEEPSUFFIX
 "self-insert", selfinsert, ZLE_MENUCMP | ZLE_KEEPSUFFIX
 "self-insert-unmeta", selfinsertunmeta, ZLE_MENUCMP | ZLE_KEEPSUFFIX
 "send-break", sendbreak, 0
diff --git a/Src/Zle/textobjects.c b/Src/Zle/textobjects.c
new file mode 100644
index 0000000..7f049c5
--- /dev/null
+++ b/Src/Zle/textobjects.c
@@ -0,0 +1,321 @@
+/*
+ * textobjects.c - ZLE module implementing Vim style text objects
+ *
+ * This file is part of zsh, the Z shell.
+ *
+ * Copyright (c) 2014 Oliver Kiddle
+ * All rights reserved.
+ *
+ * Permission is hereby granted, without written agreement and without
+ * license or royalty fees, to use, copy, modify, and distribute this
+ * software and to distribute modified versions of this software for any
+ * purpose, provided that the above copyright notice and the following
+ * two paragraphs appear in all copies of this software.
+ *
+ * In no event shall Oliver Kiddle or the Zsh Development Group be liable
+ * to any party for direct, indirect, special, incidental, or consequential
+ * damages arising out of the use of this software and its documentation,
+ * even if Oliver Kiddle and the Zsh Development Group have been advised of
+ * the possibility of such damage.
+ *
+ * Oliver Kiddle and the Zsh Development Group specifically disclaim any
+ * warranties, including, but not limited to, the implied warranties of
+ * merchantability and fitness for a particular purpose.  The software
+ * provided hereunder is on an "as is" basis, and Oliver Kiddle and the
+ * Zsh Development Group have no obligation to provide maintenance,
+ * support, updates, enhancements, or modifications.
+ *
+ */
+
+#include "zle.mdh"
+#include "textobjects.pro"
+
+/* class of character: 0 is whitespace, 1 is word character, 2 is other */
+static int
+wordclass(ZLE_CHAR_T x)
+{
+    return (ZC_iblank(x) ? 0 : ((ZC_ialnum(x) || (ZWC('_') == x)) ? 1 : 2));
+}
+
+static int
+blankwordclass(ZLE_CHAR_T x)
+{
+    return (ZC_iblank(x) ? 0 : 1);
+}
+
+/**/
+int
+selectword(UNUSED(char **args))
+{
+    int n = zmult;
+    int all = (bindk == t_selectaword || bindk == t_selectablankword);
+    int (*viclass)(ZLE_CHAR_T) = (bindk == t_selectaword ||
+	    bindk == t_selectinword) ? wordclass : blankwordclass;
+    int sclass = viclass(zleline[zlecs]);
+    int doblanks = all && sclass;
+
+    if (!invicmdmode()) {
+	region_active = 1;
+	mark = zlecs;
+    }
+    if (!region_active || zlecs == mark) {
+	/* search back to first character of same class as the start position
+	 * also stop at the beginning of the line */
+	mark = zlecs;
+	while (mark) {
+	    int pos = mark;
+	    DECPOS(pos);
+	    if (zleline[pos] == ZWC('\n') || viclass(zleline[pos]) != sclass)
+		break;
+	    mark = pos;
+	}
+	/* similarly scan forward over characters of the same class */
+	while (zlecs < zlell) {
+	    INCCS();
+	    int pos = zlecs;
+	    /* single newlines within blanks are included */
+	    if (all && !sclass && pos < zlell && zleline[pos] == ZWC('\n'))
+		INCPOS(pos);
+
+	    if (zleline[pos] == ZWC('\n') || viclass(zleline[pos]) != sclass)
+		break;
+	}
+
+	if (all) {
+	    int nclass = viclass(zleline[zlecs]);
+	    /* if either start or new position is blank advance over
+	     * a new block of characters of a common type */
+	    if (!nclass || !sclass) {
+		while (zlecs < zlell) {
+		    INCCS();
+		    if (zleline[zlecs] == ZWC('\n') ||
+			    viclass(zleline[zlecs]) != nclass)
+			break;
+		}
+		if (n < 2)
+		    doblanks = 0;
+	    }
+	}
+    } else {
+	/* For visual mode, advance one char so repeated
+	 * invocations select subsequent words */
+	if (zlecs > mark) {
+	    if (zlecs < zlell)
+		INCCS();
+	} else if (zlecs)
+	    DECCS();
+	if (zlecs < mark) {
+	    /* visual mode with the cursor before the mark: move cursor back */
+	    while (n-- > 0) {
+		int pos = zlecs;
+		/* first over blanks */
+		if (all && (!viclass(zleline[pos]) ||
+			zleline[pos] == ZWC('\n'))) {
+		    all = 0;
+		    while (pos) {
+			DECPOS(pos);
+			if (zleline[pos] == ZWC('\n'))
+			    break;
+			zlecs = pos;
+			if (viclass(zleline[pos]))
+			    break;
+		    }
+		} else if (zlecs && zleline[zlecs] == ZWC('\n')) {
+		    /* for in widgets pass over one newline */
+		    DECPOS(pos);
+		    if (zleline[pos] != ZWC('\n'))
+			zlecs = pos;
+		}
+		pos = zlecs;
+		sclass = viclass(zleline[zlecs]);
+		/* now retreat over non-blanks */
+		while (zleline[pos] != ZWC('\n') &&
+			viclass(zleline[pos]) == sclass) {
+		    zlecs = pos;
+		    if (!pos) {
+			zlecs = 0;
+			break;
+		    }
+		    DECPOS(pos);
+		}
+		/* blanks again but only if there were none first time */
+		if (all && zlecs) {
+		    pos = zlecs;
+		    DECPOS(pos);
+		    if (!viclass(zleline[pos])) {
+			while (pos) {
+			    DECPOS(pos);
+			    if (zleline[pos] == ZWC('\n') ||
+				    viclass(zleline[pos]))
+				break;
+			    zlecs = pos;
+			}
+		    }
+		}
+	    }
+	    return 0;
+	}
+	n++;
+	doblanks = 0;
+    }
+    region_active = !!region_active; /* force to character wise */
+
+    /* for each digit argument, advance over further block of one class */
+    while (--n > 0) {
+	if (zlecs < zlell && zleline[zlecs] == ZWC('\n'))
+	    INCCS();
+	sclass = viclass(zleline[zlecs]);
+	while (zlecs < zlell) {
+	    INCCS();
+	    if (zleline[zlecs] == ZWC('\n') ||
+		    viclass(zleline[zlecs]) != sclass)
+		break;
+	}
+	/* for 'a' widgets, advance extra block if either consists of blanks */
+	if (all) {
+	    if (zlecs < zlell && zleline[zlecs] == ZWC('\n'))
+		INCCS();
+	    if (!sclass || !viclass(zleline[zlecs]) ) {
+		sclass = viclass(zleline[zlecs]);
+		if (n == 1 && !sclass)
+		    doblanks = 0;
+		while (zlecs < zlell) {
+		    INCCS();
+		    if (zleline[zlecs] == ZWC('\n') ||
+			    viclass(zleline[zlecs]) != sclass)
+			break;
+		}
+	    }
+	}
+    }
+
+    /* if we didn't remove blanks at either end we remove some at the start */
+    if (doblanks) {
+	int pos = mark;
+	while (pos) {
+	    DECPOS(pos);
+	    /* don't remove blanks at the start of the line, i.e indentation */
+	    if (zleline[pos] == ZWC('\n'))
+		break;
+	    if (!ZC_iblank(zleline[pos])) {
+		INCPOS(pos);
+		mark = pos;
+		break;
+	    }
+	}
+    }
+    /* Adjustment: vi operators don't include the cursor position, in insert
+     * or emacs mode the region also doesn't but for vi visual mode it is
+     * included. */
+    if (zlecs && zlecs > mark && !virangeflag)
+	DECCS();
+
+    return 0;
+}
+
+/**/
+int
+selectargument(UNUSED(char **args))
+{
+    int ne = noerrs, ocs = zlemetacs;
+    int owb = wb, owe= we, oadx = addedx, ona = noaliases;
+    char *p;
+    int ll, cs;
+    char *linein;
+    int wend = 0, wcur = 0;
+    int n = zmult;
+    int *wstarts;
+    int tmpsz;
+
+    if (n < 1 || 2*n > zlell + 1)
+	return 1;
+
+    /* if used from emacs mode enable the region */
+    if (!invicmdmode()) {
+	region_active = 1;
+	mark = zlecs;
+    }
+
+    wstarts = (int *) zhalloc(n * sizeof(int));
+    memset(wstarts, 0, n * sizeof(int));
+
+    addedx = 0;
+    noerrs = 1;
+    lexsave();
+    lexflags = LEXFLAGS_ACTIVE;
+    linein = zlegetline(&ll, &cs);
+    zlemetall = ll;
+    zlemetacs = cs;
+
+    if (!isfirstln && chline) {
+       p = (char *) zhalloc(hptr - chline + zlemetall + 2);
+       memcpy(p, chline, hptr - chline);
+       memcpy(p + (hptr - chline), linein, ll);
+       p[(hptr - chline) + ll] = '\0';
+       inpush(p, 0, NULL);
+       zlemetacs += hptr - chline;
+    } else {
+       p = (char *) zhalloc(ll + 1);
+       memcpy(p, linein, ll);
+       p[ll] = '\0';
+       inpush(p, 0, NULL);
+    }
+    if (zlemetacs)
+       zlemetacs--;
+    strinbeg(0);
+    noaliases = 1;
+    do {
+       wstarts[wcur++] = wend;
+       wcur %= n;
+       ctxtlex();
+       if (tok == ENDINPUT || tok == LEXERR)
+           break;
+       wend = zlemetall - inbufct;
+    } while (tok != ENDINPUT && tok != LEXERR && wend <= zlemetacs);
+    noaliases = ona;
+    strinend();
+    inpop();
+    errflag = 0;
+    noerrs = ne;
+    lexrestore();
+    zlemetacs = ocs;
+    wb = owb;
+    we = owe;
+    addedx = oadx;
+
+    /* convert offsets for mark and zlecs back to ZLE internal format */
+    linein[wend] = '\0'; /* a bit of a hack to get two offsets */
+    free(stringaszleline(linein, wstarts[wcur], &zlecs, &tmpsz, &mark));
+
+    if (bindk == t_selectinshellword) {
+	ZLE_CHAR_T *match = ZWS("`\'\"");
+	ZLE_CHAR_T *lmatch = ZWS("\'({"), *rmatch = ZWS("\')}");
+	ZLE_CHAR_T *ematch = match, *found;
+	int start, end = zlecs;
+	/* for 'in' widget, don't include initial blanks ... */
+	while (mark < zlecs && ZC_iblank(zleline[mark]))
+	    INCPOS(mark);
+	/* ... or a matching pair of quotes */
+	start = mark;
+	if (zleline[start] == ZWC('$')) {
+	    match = lmatch;
+	    ematch = rmatch;
+	    INCPOS(start);
+	}
+	found = ZS_strchr(match, zleline[start]);
+	if (found) {
+	    DECPOS(end);
+	    if (zleline[end] == ematch[found-match]) {
+		zlecs = end;
+		INCPOS(start);
+		mark = start;
+	    }
+	}
+    }
+
+    /* Adjustment: vi operators don't include the cursor position */
+    if (!virangeflag)
+       DECCS();
+
+    return 0;
+}
diff --git a/Src/Zle/zle.mdd b/Src/Zle/zle.mdd
index c6e4d11..dd69eff 100644
--- a/Src/Zle/zle.mdd
+++ b/Src/Zle/zle.mdd
@@ -7,7 +7,8 @@ autofeatures="b:bindkey b:vared b:zle"
 
 objects="zle_bindings.o zle_hist.o zle_keymap.o zle_main.o \
 zle_misc.o zle_move.o zle_params.o zle_refresh.o \
-zle_thingy.o zle_tricky.o zle_utils.o zle_vi.o zle_word.o"
+zle_thingy.o zle_tricky.o zle_utils.o zle_vi.o zle_word.o \
+textobjects.o"
 
 headers="zle.h zle_things.h"
 
diff --git a/Src/Zle/zle_keymap.c b/Src/Zle/zle_keymap.c
index 216e302..30d25eb 100644
--- a/Src/Zle/zle_keymap.c
+++ b/Src/Zle/zle_keymap.c
@@ -1343,6 +1343,12 @@ default_bindings(void)
 	add_cursor_key(kptr, TCDOWNCURSOR, t_downline, 'B');
 	bindkey(kptr, "k", refthingy(t_upline), NULL);
 	bindkey(kptr, "j", refthingy(t_downline), NULL);
+	bindkey(kptr, "aa", refthingy(t_selectashellword), NULL);
+	bindkey(kptr, "ia", refthingy(t_selectinshellword), NULL);
+	bindkey(kptr, "aw", refthingy(t_selectaword), NULL);
+	bindkey(kptr, "iw", refthingy(t_selectinword), NULL);
+	bindkey(kptr, "aW", refthingy(t_selectablankword), NULL);
+	bindkey(kptr, "iW", refthingy(t_selectinblankword), NULL);
     }
     /* escape in operator pending cancels the operation */
     bindkey(oppmap, "\33", refthingy(t_vicmdmode), NULL);
diff --git a/Test/X02zlevi.ztst b/Test/X02zlevi.ztst
index 94afb60..6b7ca56 100644
--- a/Test/X02zlevi.ztst
+++ b/Test/X02zlevi.ztst
@@ -382,6 +382,45 @@
 >BUFFER: -
 >CURSOR: 0
 
+  zletest $'----    word    ----word\eo    \eo----\eodone\eh' \
+      'vhawmaawmbawmcawmdawmeawmfawmgv`ara`brb`crc$r$`drd`ere`frf`grg'
+0:all word with existing selection and cursor before mark
+>BUFFER: g---f   worde   ----dord
+>c  $
+>b---
+>aone
+>CURSOR: 0
+
+  zletest $'----    word    word----\e0lvlawmaawmbawmcawvrd`ara`brb`crc'
+0:all word with existing selection and mark before cursor
+>BUFFER: ----   aword   bworc---d
+>CURSOR: 19
+
+  zletest $' --ww  ww---\eo\eoww\evhiwiw' m{a,b,c,d,e}iw vrE \`{a,b,c,d,e}r.
+0:in word with existing selection and cursor before mark
+>BUFFER: E.-.w. .w.--
+>
+>ww
+>CURSOR: 1
+
+  zletest $'  --ww  ww--\eO  \ev0o' m{a,b,c,d,e}iw vrE \`{a,b,c,d,e}r.
+0:in word with existing selection and mark before cursor
+>BUFFER:  .
+> .-.w. .wE--
+>CURSOR: 10
+
+  zletest $'  `one`  $(echo two) " three " $\'four\'\C-v\tfive ${six:-6}\e' \
+      vaaom{a,b,c,d,e,f}v \`{a,b,c,d,e,f}rX
+0:all argument for different arguments
+>BUFFER: X `one`X $(echo two)X" three "X$'four'XfiveX${six:-6}
+>CURSOR: 0
+
+  zletest $'{ls `echo x`  $((3+4)) "a b" $\'\\t\\n\' ${d%/}\e' \
+      cia{6,5,4,3,2,1}$'\eBB'
+0:in argument for different arguments
+>BUFFER: 1ls `2`  $(3) "4" $'5' ${6}
+>CURSOR: 0
+
 %clean
 
   zmodload -ui zsh/zpty


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

* Re: PATCH: key bindings, fixes, docs, tests for vi stuff
  2014-11-21  0:01   ` Oliver Kiddle
@ 2014-11-21  0:49     ` Bart Schaefer
  2014-11-21  1:10       ` Ray Andrews
  2014-11-21 10:35       ` Oliver Kiddle
  2014-11-21  1:15     ` Ray Andrews
  2014-11-21 15:20     ` PATCH: key bindings, fixes, docs, tests for vi stuff Jun T.
  2 siblings, 2 replies; 28+ messages in thread
From: Bart Schaefer @ 2014-11-21  0:49 UTC (permalink / raw)
  To: zsh-workers

On Nov 21,  1:01am, Oliver Kiddle wrote:
}
} + * textobjects.c - ZLE module implementing Vim style text objects

This isn't actually a "module" is it?  It's just part of the ZLE vi
widget set?

I have from time to time wondered if segregating some of the builtin
widgets into loadable modules might be beneficial.


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

* Re: PATCH: key bindings, fixes, docs, tests for vi stuff
  2014-11-21  0:49     ` Bart Schaefer
@ 2014-11-21  1:10       ` Ray Andrews
  2014-11-21  5:53         ` Bart Schaefer
  2014-11-21 10:35       ` Oliver Kiddle
  1 sibling, 1 reply; 28+ messages in thread
From: Ray Andrews @ 2014-11-21  1:10 UTC (permalink / raw)
  To: zsh-workers

On 11/20/2014 04:49 PM, Bart Schaefer wrote:
> On Nov 21,  1:01am, Oliver Kiddle wrote:
> }
> } + * textobjects.c - ZLE module implementing Vim style text objects
>
> This isn't actually a "module" is it?  It's just part of the ZLE vi
> widget set?
>
> I have from time to time wondered if segregating some of the builtin
> widgets into loadable modules might be beneficial.
Since they can autoload, why would one not put as much stuff as possible 
into modules?
Keep the central binary as trim as possible? I guess speed could be a 
concern, but
really how much?


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

* Re: PATCH: key bindings, fixes, docs, tests for vi stuff
  2014-11-21  0:01   ` Oliver Kiddle
  2014-11-21  0:49     ` Bart Schaefer
@ 2014-11-21  1:15     ` Ray Andrews
  2014-11-21  2:20       ` Mikael Magnusson
  2014-11-21 15:20     ` PATCH: key bindings, fixes, docs, tests for vi stuff Jun T.
  2 siblings, 1 reply; 28+ messages in thread
From: Ray Andrews @ 2014-11-21  1:15 UTC (permalink / raw)
  To: zsh-workers

pts/11 HP-y5--5-Debian1 root /aMisc/Ray1 $ l Etc/FA1:

text.c:865: unknown word code in gettext2()
82: text.c:865: unknown word code in gettext2()
178: text.c:865: unknown word code in gettext2()
178: text.c:865: unknown word code in gettext2()
1: text.c:865: unknown word code in gettext2()
117: text.c:865: unknown word code in gettext2()
38: text.c:865: unknown word code in gettext2()
40: text.c:865: unknown word code in gettext2()
1: text.c:865: unknown word code in gettext2()
15: text.c:865: unknown word code in gettext2()
115: text.c:865: unknown word code in gettext2()
118: text.c:865: unknown word code in gettext2()
18: text.c:865: unknown word code in gettext2()
121: text.c:865: unknown word code in gettext2()
17: text.c:865: unknown word code in gettext2()
864: text.c:865: unknown word code in gettext2()
Q.yo
zsh-5.0.7-86-ga3cc409

That popped up as I was trying to complete '/Etc/FAQ.yo'


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

* Re: PATCH: key bindings, fixes, docs, tests for vi stuff
  2014-11-21  1:15     ` Ray Andrews
@ 2014-11-21  2:20       ` Mikael Magnusson
  2014-11-21  2:38         ` Ray Andrews
  0 siblings, 1 reply; 28+ messages in thread
From: Mikael Magnusson @ 2014-11-21  2:20 UTC (permalink / raw)
  To: Ray Andrews; +Cc: zsh workers

On Fri, Nov 21, 2014 at 2:15 AM, Ray Andrews <rayandrews@eastlink.ca> wrote:
> pts/11 HP-y5--5-Debian1 root /aMisc/Ray1 $ l Etc/FA1:
>
> text.c:865: unknown word code in gettext2()
> 82: text.c:865: unknown word code in gettext2()
> 178: text.c:865: unknown word code in gettext2()
> 178: text.c:865: unknown word code in gettext2()
> 1: text.c:865: unknown word code in gettext2()
> 117: text.c:865: unknown word code in gettext2()
> 38: text.c:865: unknown word code in gettext2()
> 40: text.c:865: unknown word code in gettext2()
> 1: text.c:865: unknown word code in gettext2()
> 15: text.c:865: unknown word code in gettext2()
> 115: text.c:865: unknown word code in gettext2()
> 118: text.c:865: unknown word code in gettext2()
> 18: text.c:865: unknown word code in gettext2()
> 121: text.c:865: unknown word code in gettext2()
> 17: text.c:865: unknown word code in gettext2()
> 864: text.c:865: unknown word code in gettext2()
> Q.yo
> zsh-5.0.7-86-ga3cc409
>
> That popped up as I was trying to complete '/Etc/FAQ.yo'

If you use dev versions of zsh, you will sometimes need to manually
purge your .zwc files as they're not compatible across some code
changes. We bump the version on release and avoid loading them in that
case, but when running code from git there is no way to detect this
currently. (I suppose we could stick the patchlevel in there, but that
would invalidate the wordcode needlessly often).

-- 
Mikael Magnusson


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

* Re: PATCH: key bindings, fixes, docs, tests for vi stuff
  2014-11-21  2:20       ` Mikael Magnusson
@ 2014-11-21  2:38         ` Ray Andrews
  2014-11-21  6:23           ` Bart Schaefer
  0 siblings, 1 reply; 28+ messages in thread
From: Ray Andrews @ 2014-11-21  2:38 UTC (permalink / raw)
  To: zsh-workers

On 11/20/2014 06:20 PM, Mikael Magnusson wrote:


> If you use dev versions of zsh, you will sometimes need to manually 
> purge your .zwc files as they're not compatible across some code 
> changes. We bump the version on release and avoid loading them in that 
> case, but when running code from git there is no way to detect this 
> currently. (I suppose we could stick the patchlevel in there, but that 
> would invalidate the wordcode needlessly often). 
Thanks for the tip.  I trust these files are rebuilt at some point?
Anyway, I deleted all of them and:

pts/13 HP-y5--5-Debian1 root /aMisc/Ray1 $ git pull
zsh-5.0.7-86-ga3cc409
Already up-to-date.

pts/13 HP-y5--5-Debian1 root /aMisc/Ray1 $ make -s
zsh-5.0.7-86-ga3cc409
`stamp-modobjs' is up to date.


pts/13 HP-y5--5-Debian1 root /aMisc/Ray1 $ Src/zsh
zsh-5.0.7-86-ga3cc409
6: text.c:865: unknown word code in gettext2()
1: text.c:865: unknown word code in gettext2()
7: text.c:865: unknown word code in gettext2()
8: text.c:865: unknown word code in gettext2()

... and when I try the same completion as above, the errors are just the 
same.



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

* Re: PATCH: key bindings, fixes, docs, tests for vi stuff
  2014-11-21  1:10       ` Ray Andrews
@ 2014-11-21  5:53         ` Bart Schaefer
  0 siblings, 0 replies; 28+ messages in thread
From: Bart Schaefer @ 2014-11-21  5:53 UTC (permalink / raw)
  To: zsh-workers

On Nov 20,  5:10pm, Ray Andrews wrote:
}
} Since they can autoload, why would one not put as much stuff as possible 
} into modules?

In this case they *are* in a module.  I'm just talking about possibly
making two or more smaller modules out of the one they're in.


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

* Re: PATCH: key bindings, fixes, docs, tests for vi stuff
  2014-11-21  2:38         ` Ray Andrews
@ 2014-11-21  6:23           ` Bart Schaefer
  2014-11-21 17:28             ` trouble with debugging binary Ray Andrews
  0 siblings, 1 reply; 28+ messages in thread
From: Bart Schaefer @ 2014-11-21  6:23 UTC (permalink / raw)
  To: zsh-workers

On Nov 20,  6:38pm, Ray Andrews wrote:
} Subject: Re: PATCH: key bindings, fixes, docs, tests for vi stuff

Please don't hijack threads by hitting "reply" and then starting a
whole new conversation.  If you have a new topic, start a new message.
Thanks.

} On 11/20/2014 06:20 PM, Mikael Magnusson wrote:
} 
} > If you use dev versions of zsh, you will sometimes need to manually 
} > purge your .zwc files as they're not compatible across some code 
} > changes.
} 
} Thanks for the tip.  I trust these files are rebuilt at some point?

There's nothing that automatically rebuilds .zwc files in the regular
zsh distribution or "make" process.  If you have .zwc files in your
$fpath, either you zcompile'd them, or they were zcompile'd for the
zsh package installed with your OS package manager (which seems not
very likely).

} Anyway, I deleted all of them and:

Where were they before you deleted them?

} 6: text.c:865: unknown word code in gettext2()
} 1: text.c:865: unknown word code in gettext2()
} 7: text.c:865: unknown word code in gettext2()
} 8: text.c:865: unknown word code in gettext2()

This is a bit suspicious because gettext2() is only called when turning
a wordcode program back into readable text; for example, when calling
a DEBUG trap or preexec.


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

* Re: PATCH: key bindings, fixes, docs, tests for vi stuff
  2014-11-21  0:49     ` Bart Schaefer
  2014-11-21  1:10       ` Ray Andrews
@ 2014-11-21 10:35       ` Oliver Kiddle
  2014-11-22  6:59         ` Bart Schaefer
  1 sibling, 1 reply; 28+ messages in thread
From: Oliver Kiddle @ 2014-11-21 10:35 UTC (permalink / raw)
  To: zsh-workers

Bart wrote:
> } + * textobjects.c - ZLE module implementing Vim style text objects
> 
> This isn't actually a "module" is it?  It's just part of the ZLE vi
> widget set?

Yes. It was when I wrote that text.

> I have from time to time wondered if segregating some of the builtin
> widgets into loadable modules might be beneficial.

This is something I was also pondering. The main obstacle to this, and
the reason I pulled textobjects inline, relates to keybindings:

If someone has their bindkey commands early in .zshrc, we don't want
those to be overridden later when a module gets loaded. This problem
already means everyone has to take care to put their listscroll and
menuselect bindings late in their .zshrc.

As one solution, we could have all default bindings in zle.so. I haven't
checked what happens if that includes bindings to autoloadable widgets:
(i.e. if it is possible and if so whether that results in instant or
deferred loading). I wouldn't want a module for execute-named-cmd loaded
just because I want to bind a few keys in the command keymap but I'd
want the keymap to be there.

Do you have any thoughts on what a logical division into modules would
be? I was thinking along the lines of the vi/emacs split but only for
those widgets that are unlikely to be used for the opposite mode.
We might also have a few smaller modules, e.g. for execute-named-cmd. I
use a shell function replacement that uses read-from-minibuffer.

The only existing module: deltochar appears to be mainly there to
provide an example of doing widgets as a module. Is it a fairly much
standard thing to an emacs user or is it logical to have it on its own?

I also wonder if we could make it possible for shell function widgets
to specify some sort of default key binding much as is possible for
completion widgets. For text objects I was going to mostly use shell
functions. Of the two existing ones, shell-word needs the lexer and
basic words are sort of fundamental. I've perhaps made them more vim
compatible than was necessary except where the vim behaviour looks like
a bug (successive newlines and the first character in the buffer).

Oliver


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

* Re: PATCH: key bindings, fixes, docs, tests for vi stuff
  2014-11-21  0:01   ` Oliver Kiddle
  2014-11-21  0:49     ` Bart Schaefer
  2014-11-21  1:15     ` Ray Andrews
@ 2014-11-21 15:20     ` Jun T.
  2 siblings, 0 replies; 28+ messages in thread
From: Jun T. @ 2014-11-21 15:20 UTC (permalink / raw)
  To: zsh-workers

2014/11/21 09:01, Oliver Kiddle <okiddle@yahoo.co.uk> wrote:

> On 18 Nov, "Jun T." wrote:
>> Apparently 'daw' is not working.
> 
> With this patch, that test failure should now be fixed.

Yes, it has been fixed.
But now I get another failure on my Mac:

*** 1,2 ****
! BUFFER: X `one`X $(echo two)X" three "X$'four'XfiveX${six:-6}
  CURSOR: 0
--- 1,2 ----
! BUFFER: X `one`X $(echo two)X" three "X$'four'fiveX${six:-6}
  CURSOR: 0
Test ./X02zlevi.ztst failed: output differs from expected as shown above for:
  zletest $'  `one`  $(echo two) " three " $\'four\'\C-v\tfive ${six:-6}\e' \
      vaaom{a,b,c,d,e,f}v \`{a,b,c,d,e,f}rX
Was testing: all argument for different arguments

This is due to that ^V is interpreted as the 'lnext' control character
by the slave tty. 
Yet another ad hoc workaround is to modify line 37 of Test/comptest to

stty 38400 columns 80 rows 24 tabs werase undef lnext undef

Here, 'lnext undef' can be replaced by '-iexten'.
Surprisingly (at least to me), 'werase undef' can also be replaced by
'-icanon' for the tests including '^W' to succeed:

stty 38400 columns 80 rows 24 tabs -icanon -iexten

'bindkey -r "\e~"' is still required for the test 'swap case on a blank line'
to succeed.

Jun


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

* trouble with debugging binary
  2014-11-21  6:23           ` Bart Schaefer
@ 2014-11-21 17:28             ` Ray Andrews
  2014-11-22  4:45               ` Bart Schaefer
  0 siblings, 1 reply; 28+ messages in thread
From: Ray Andrews @ 2014-11-21 17:28 UTC (permalink / raw)
  To: zsh-workers

On 11/20/2014 10:23 PM, Bart Schaefer wrote:
> Please don't hijack threads by hitting "reply" and then starting a
> whole new conversation.  If you have a new topic, start a new message.
> Thanks.
Pardon, it morphed out  of what seemed like an error report on that topic.
>
> } Anyway, I deleted all of them and:
>
> Where were they before you deleted them?
All in
/usr/share/zsh/functions
/usr/share/zsh/functions/Completions

I'll restore  them. No doubt they do something important,
but I'm not noticing their absence right now.

Is there some sort of global map of everything that zsh adds to
one's system? These *.zwc files, I had no idea they were there
and I have no idea what they do.

} 6: text.c:865: unknown word code in gettext2()
} 1: text.c:865: unknown word code in gettext2()
} 7: text.c:865: unknown word code in gettext2()
} 8: text.c:865: unknown word code in gettext2()

} This is a bit suspicious because gettext2() is only called when turning
a wordcode program back into readable text; for example, when calling
a DEBUG trap or preexec.

... I can't say. I have this (which you helped me with some time ago):

typeset -g TLC
TRAPDEBUG()
{
   (( $#functrace == 1 )) && TLC=(${(z)ZSH_DEBUG_CMD})
}

I just rebuild without  " --enable-zsh-debug " and all is well.

Removing the above function, all is well with the debugging binary.

So none of this had anything to do with the 'vi' patches and
everything to do with TRAPDEBUG not liking the debugging binary.
Tho one might expect that a specifically debugging function would
go well with a specifically debugging binary.


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

* Re: trouble with debugging binary
  2014-11-21 17:28             ` trouble with debugging binary Ray Andrews
@ 2014-11-22  4:45               ` Bart Schaefer
  2014-11-22  5:27                 ` Ray Andrews
  2014-11-22  5:43                 ` Bart Schaefer
  0 siblings, 2 replies; 28+ messages in thread
From: Bart Schaefer @ 2014-11-22  4:45 UTC (permalink / raw)
  To: zsh-workers

On Nov 21,  9:28am, Ray Andrews wrote:
} Subject: trouble with debugging binary
}
} On 11/20/2014 10:23 PM, Bart Schaefer wrote:
} >
} > Where were they before you deleted them?
} All in
} /usr/share/zsh/functions
} /usr/share/zsh/functions/Completions
} 
} I'll restore  them. No doubt they do something important,
} but I'm not noticing their absence right now.

No, actually, they're entirely unimportant; they're just the compiled
(into zsh's internal word code) versions of the functions that share
their base name.  In some cases it can be faster to load a pre-compiled
function file, so zsh has the "zcompile" builtin for creating them.
But the chances you'd notice the difference from them not being there,
are small.

} Is there some sort of global map of everything that zsh adds to
} one's system? These *.zwc files, I had no idea they were there
} and I have no idea what they do.

As I said, they're NOT something that zsh added to the system.  It must
be that the package for your OS's stock zsh binary included them.

} I just rebuild without  " --enable-zsh-debug " and all is well.

Sadly, rebuilding without --enable-zsh-debug is sort of like removing
the batteries from your smoke detector.  There may still be a fire, but
you just aren't hearing about it any more.


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

* Re: trouble with debugging binary
  2014-11-22  4:45               ` Bart Schaefer
@ 2014-11-22  5:27                 ` Ray Andrews
  2014-11-22  5:43                 ` Bart Schaefer
  1 sibling, 0 replies; 28+ messages in thread
From: Ray Andrews @ 2014-11-22  5:27 UTC (permalink / raw)
  To: zsh-workers

    Sadly, rebuilding without --enable-zsh-debug is sort of like
    removing the batteries from your smoke detector. There may still be
    a fire, but you just aren't hearing about it any more.


I just played with --enable-zsh-debug a bit more, and funny thing is 
that the errors
sorta just go away after a while, if you give it time.  By the third 
attempt at a
completion, everything is just fine. God knows.

    pts/5 HP-y5--5-Debian1 root /aMisc/Ray1/Src $ ./zsh,1,debugging
    zsh-5.0.7-86-ga3cc409
    6: text.c:865: unknown word code in gettext2()
    1: text.c:865: unknown word code in gettext2()
    7: text.c:865: unknown word code in gettext2()
    8: text.c:865: unknown word code in gettext2()

... but it always does that on starting that binary.

Fiddling with it:

    typeset -g TLC
    TRAPDEBUG()
    {
    }

... even when the function is empty, the error is still there.


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

* Re: trouble with debugging binary
  2014-11-22  4:45               ` Bart Schaefer
  2014-11-22  5:27                 ` Ray Andrews
@ 2014-11-22  5:43                 ` Bart Schaefer
  2014-11-22 16:49                   ` Ray Andrews
  1 sibling, 1 reply; 28+ messages in thread
From: Bart Schaefer @ 2014-11-22  5:43 UTC (permalink / raw)
  To: zsh-workers

On Nov 21,  8:45pm, Bart Schaefer wrote:
}
} Sadly, rebuilding without --enable-zsh-debug is sort of like removing
} the batteries from your smoke detector.  There may still be a fire, but
} you just aren't hearing about it any more.

And indeed, there really WAS an "unknown word code".  Except it was only
unknown to gettext2().

Turns out that gettext2() predates the DEBUG_BEFORE_CMD option, and that
there is one word code that can't possibly appear when the command text
is examined after the command is executed, and therefore gettext2() did
not bother about understanding that particular word code.

The initial guess about out-of-date .zwc files was a red herring.


diff --git a/Src/text.c b/Src/text.c
index f55553e..75f642c 100644
--- a/Src/text.c
+++ b/Src/text.c
@@ -834,6 +834,10 @@ gettext2(Estate state)
 	    taddstr("))");
 	    stack = 1;
 	    break;
+	case WC_AUTOFN:
+	    taddstr("builtin autoload -X");
+	    stack = 1;
+	    break;
 	case WC_TRY:
 	    if (!s) {
 		taddstr("{");


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

* Re: PATCH: key bindings, fixes, docs, tests for vi stuff
  2014-11-21 10:35       ` Oliver Kiddle
@ 2014-11-22  6:59         ` Bart Schaefer
  2014-12-12 16:47           ` Oliver Kiddle
  0 siblings, 1 reply; 28+ messages in thread
From: Bart Schaefer @ 2014-11-22  6:59 UTC (permalink / raw)
  To: zsh-workers

On Nov 21, 11:35am, Oliver Kiddle wrote:
}
} Bart wrote:
} > I have from time to time wondered if segregating some of the builtin
} > widgets into loadable modules might be beneficial.
} 
} This is something I was also pondering. The main obstacle to this, and
} the reason I pulled textobjects inline, relates to keybindings:
} 
} If someone has their bindkey commands early in .zshrc, we don't want
} those to be overridden later when a module gets loaded.  This problem
} already means everyone has to take care to put their listscroll and
} menuselect bindings late in their .zshrc.

Hmm, those seem like two different sides of the coin.  Is it not the
case that the listscroll and menuselect bindings have to be late
because the keymaps don't yet exist?  Thus not because the bindings
would be overridden?  I suppose re-creating the keymap is a form of
override.

But it shouldn't be that difficult to have the modules check for the
existence of the keymap, skip re-creating it it if it's already there,
and then only add bindings that don't conflict?

} As one solution, we could have all default bindings in zle.so. I haven't
} checked what happens if that includes bindings to autoloadable widgets:

Hmm again.  As of right now, I think that would cause the entire module
to load as soon as you attempted to use the binding, which in the case
of e.g. menuselect would re-initialize the keymap and possibly destroy
the binding you just used.

} Do you have any thoughts on what a logical division into modules would
} be? I was thinking along the lines of the vi/emacs split but only for
} those widgets that are unlikely to be used for the opposite mode.

It's difficult to decide.  There are the functional divisions in the
documentation (Movement, History Control, etc.) and then the major
divisions of emacs/vi.

Maybe the way to do it is:

- common default bindings (accept-line, clear-screen, etc.)
- emacs default bindings
- unbound emacs widgets
- vi default bindings
- unbound vi widgets

and then some other modules for miscellaneous stuff that is neither
bound by default, nor really fits into either major editor style
(auto-suffix-retain/remove, read-command, recursive-edit, split-undo,
etc.).  [Maybe there should be a "widgets for use from other widgets"
category.]

} The only existing module: deltochar appears to be mainly there to
} provide an example of doing widgets as a module. Is it a fairly much
} standard thing to an emacs user or is it logical to have it on its own?

I've never used it, but zap-to-char is a standard GNU emacs binding
these days, so perhaps others do.
 
} I also wonder if we could make it possible for shell function widgets
} to specify some sort of default key binding much as is possible for
} completion widgets.

The widgets don't really specify their key binding, that's all done by
compinit when it scans $fpath for #compdef lines.  We could easily have
another such script that looks for a different #something.  There is
already #autoload but it doesn't do bindings.


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

* Re: trouble with debugging binary
  2014-11-22  5:43                 ` Bart Schaefer
@ 2014-11-22 16:49                   ` Ray Andrews
  2014-11-22 22:35                     ` Bart Schaefer
  2014-11-23  7:58                     ` Lawrence Velázquez
  0 siblings, 2 replies; 28+ messages in thread
From: Ray Andrews @ 2014-11-22 16:49 UTC (permalink / raw)
  To: zsh-workers

On 11/21/2014 09:43 PM, Bart Schaefer wrote:
>   	    break;
> +	case WC_AUTOFN:
> +	    taddstr("builtin autoload -X");
> +	    stack = 1;
> +	    break;
>   
Yoku dekimashita Sensei

These patches, they don't look like normal diffs, is it a git
exclusive? Are they applied by some git subcommand?


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

* Re: trouble with debugging binary
  2014-11-22 16:49                   ` Ray Andrews
@ 2014-11-22 22:35                     ` Bart Schaefer
  2014-11-23  7:58                     ` Lawrence Velázquez
  1 sibling, 0 replies; 28+ messages in thread
From: Bart Schaefer @ 2014-11-22 22:35 UTC (permalink / raw)
  To: zsh-workers

On Nov 22,  8:49am, Ray Andrews wrote:
} Subject: Re: trouble with debugging binary
}
} These patches, they don't look like normal diffs, is it a git
} exclusive? Are they applied by some git subcommand?

They're just "git diff" output, I hadn't notice them being something
that couldn't be fed to "patch" but AFAIK there is no magic git way
to apply them.  However, I've already pushed this one so you should
be able to "git pull" it.


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

* Re: trouble with debugging binary
  2014-11-22 16:49                   ` Ray Andrews
  2014-11-22 22:35                     ` Bart Schaefer
@ 2014-11-23  7:58                     ` Lawrence Velázquez
  2014-11-23 16:22                       ` Ray Andrews
  1 sibling, 1 reply; 28+ messages in thread
From: Lawrence Velázquez @ 2014-11-23  7:58 UTC (permalink / raw)
  To: Ray Andrews; +Cc: zsh-workers

On Nov 22, 2014, at 11:49 AM, Ray Andrews <rayandrews@eastlink.ca> wrote:

> On 11/21/2014 09:43 PM, Bart Schaefer wrote:
>>  	    break;
>> +	case WC_AUTOFN:
>> +	    taddstr("builtin autoload -X");
>> +	    stack = 1;
>> +	    break;
>>  
> Yoku dekimashita Sensei
> 
> These patches, they don't look like normal diffs, is it a git
> exclusive? Are they applied by some git subcommand?

The "unified" format is quite common. I personally have a hard time reading diffs in other formats.

https://en.wikipedia.org/wiki/Diff_utility#Unified_format

vq

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

* Re: trouble with debugging binary
  2014-11-23  7:58                     ` Lawrence Velázquez
@ 2014-11-23 16:22                       ` Ray Andrews
  2014-11-23 18:12                         ` Mikael Magnusson
  0 siblings, 1 reply; 28+ messages in thread
From: Ray Andrews @ 2014-11-23 16:22 UTC (permalink / raw)
  To: Lawrence Velázquez; +Cc: zsh-workers

On 11/22/2014 11:58 PM, Lawrence Velázquez wrote:
> On Nov 22, 2014, at 11:49 AM, Ray Andrews <rayandrews@eastlink.ca> wrote:
Lawrence,

 >    The "unified" format is quite common. I personally have a hard 
time reading diffs in other formats. 
https://en.wikipedia.org/wiki/Diff_utility#Unified_format vq

Thanks, that is very informative.  I never looked at the switches for 
'diff'.  So this means that we can patch the output from 'git diff' then 
so long as we have the whole file?  It will be interesting to see, at 
the next 'pull' if git recognizes the patch or complains.


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

* Re: trouble with debugging binary
  2014-11-23 16:22                       ` Ray Andrews
@ 2014-11-23 18:12                         ` Mikael Magnusson
  2014-11-23 18:42                           ` Ray Andrews
  0 siblings, 1 reply; 28+ messages in thread
From: Mikael Magnusson @ 2014-11-23 18:12 UTC (permalink / raw)
  To: Ray Andrews; +Cc: zsh workers

On Sun, Nov 23, 2014 at 5:22 PM, Ray Andrews <rayandrews@eastlink.ca> wrote:
> On 11/22/2014 11:58 PM, Lawrence Velázquez wrote:
>>
>> On Nov 22, 2014, at 11:49 AM, Ray Andrews <rayandrews@eastlink.ca> wrote:
>
> Lawrence,
>
>>    The "unified" format is quite common. I personally have a hard time
>> reading diffs in other formats.
>> https://en.wikipedia.org/wiki/Diff_utility#Unified_format vq
>
> Thanks, that is very informative.  I never looked at the switches for
> 'diff'.  So this means that we can patch the output from 'git diff' then so
> long as we have the whole file?  It will be interesting to see, at the next
> 'pull' if git recognizes the patch or complains.

If you think "git pull" downloads patches and applies them locally,
you are completely mistaken :). As a sidenote, you can produce patches
with git that 'patch' cannot apply, if you specify -M and/or -C. 'git
am' or 'git apply' are always able to apply these though, of course.

I'm actually a bit confused about what you consider the 'normal' diff
format, almost nobody uses anything other than the unified format.

-- 
Mikael Magnusson


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

* Re: trouble with debugging binary
  2014-11-23 18:12                         ` Mikael Magnusson
@ 2014-11-23 18:42                           ` Ray Andrews
  2014-11-23 19:01                             ` Mikael Magnusson
  0 siblings, 1 reply; 28+ messages in thread
From: Ray Andrews @ 2014-11-23 18:42 UTC (permalink / raw)
  To: Mikael Magnusson; +Cc: zsh workers

On 11/23/2014 10:12 AM, Mikael Magnusson wrote:
>
> If you think "git pull" downloads patches and applies them locally,
> you are completely mistaken :).

I'm thinking that git does everything with 'patches', although
they might not be called that. Nevermind tho, I'm reading the
doc, and will understand it all in time. Anyway, what I meant
was that if I patch something here by hand, and then 'pull' ,
*and* that same patch has been applied upstream,
will git recognize the local patch as kosher, or will it complain that
the file has been locally changed.

Trying it, I see that git does *not* see the patch as kosher and
demands that I 'stash' it. git is very fussy, just as it should be.

> I'm actually a bit confused about what you consider the 'normal' diff
> format, almost nobody uses anything other than the unified format.
>

... just 'diff' with no switches.  Now that I try 'diff -u' I see what you
mean--that's what I normally see, I just didn't know how to produce
that format, now I do. It sure is easier to read.


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

* Re: trouble with debugging binary
  2014-11-23 18:42                           ` Ray Andrews
@ 2014-11-23 19:01                             ` Mikael Magnusson
  2014-11-23 22:30                               ` Ray Andrews
  0 siblings, 1 reply; 28+ messages in thread
From: Mikael Magnusson @ 2014-11-23 19:01 UTC (permalink / raw)
  To: Ray Andrews; +Cc: zsh workers

On Sun, Nov 23, 2014 at 7:42 PM, Ray Andrews <rayandrews@eastlink.ca> wrote:
> On 11/23/2014 10:12 AM, Mikael Magnusson wrote:
>>
>>
>> If you think "git pull" downloads patches and applies them locally,
>> you are completely mistaken :).
>
>
> I'm thinking that git does everything with 'patches', although
> they might not be called that. Nevermind tho, I'm reading the
> doc, and will understand it all in time. Anyway, what I meant
> was that if I patch something here by hand, and then 'pull' ,
> *and* that same patch has been applied upstream,
> will git recognize the local patch as kosher, or will it complain that
> the file has been locally changed.
>
> Trying it, I see that git does *not* see the patch as kosher and
> demands that I 'stash' it. git is very fussy, just as it should be.

Ah, that makes sense :). Yes, if you have anything *uncommitted*, git
will never touch it unless you specify an option that sounds like
--force or --hard or so. Note though that pull will create merge
commits for you if you have committed stuff locally, which will make
you end up with a fork of zsh.

What you may want to do if you have a few local patches is to use git
pull --rebase and it'll move your commits on top of upstream each time
(by generating patches, updating the tree, and then applying them
again). I would recommend doing this rather than carrying uncommitted
changes around in a stash forever. You can set the pull.rebase git
option in your zsh repo to true to make it the default too.

What I usually do is just 'git fetch', inspect the history with 'git
log ..@{u}' (or paste the range output from fetch), and if there's
anything I care about, I manually run 'git rebase'.

>> I'm actually a bit confused about what you consider the 'normal' diff
>> format, almost nobody uses anything other than the unified format.
>
> ... just 'diff' with no switches.  Now that I try 'diff -u' I see what you
> mean--that's what I normally see, I just didn't know how to produce
> that format, now I do. It sure is easier to read.

It's also a bit safer in that the extra context lets 'patch' detect in
more cases whether the patch has already been applied, and prevents
you from applying it twice (eg, if it only contains additions, the <>
format will happily add them in at the specified line number forever).

-- 
Mikael Magnusson


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

* Re: trouble with debugging binary
  2014-11-23 19:01                             ` Mikael Magnusson
@ 2014-11-23 22:30                               ` Ray Andrews
  0 siblings, 0 replies; 28+ messages in thread
From: Ray Andrews @ 2014-11-23 22:30 UTC (permalink / raw)
  To: Mikael Magnusson; +Cc: zsh workers

On 11/23/2014 11:01 AM, Mikael Magnusson wrote:

> What I usually do is just 'git fetch', inspect the history with 'git
> log ..@{u}' (or paste the range output from fetch), and if there's
> anything I care about, I manually run 'git rebase'.

Thanks, you're making this almost easy ;-)


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

* Re: PATCH: key bindings, fixes, docs, tests for vi stuff
  2014-11-22  6:59         ` Bart Schaefer
@ 2014-12-12 16:47           ` Oliver Kiddle
  0 siblings, 0 replies; 28+ messages in thread
From: Oliver Kiddle @ 2014-12-12 16:47 UTC (permalink / raw)
  To: zsh-workers

On 21 Nov, Bart wrote:

> But it shouldn't be that difficult to have the modules check for the
> existence of the keymap, skip re-creating it it if it's already there,
> and then only add bindings that don't conflict?

That won't work where people remove bindings. Maybe that's not too
common though I do it. Actually, looking at what I remove, I think
we should change the default binding of ^X in viins to be undefined
instead of self-insert. This is because the completion system adds a
bunch of widgets with a ^X prefix. Furthermore, vim uses ^X as a prefix
to mostly completion commands.

Coming back to the original question, it might be possible to make
keymaps a feature that causes module autoloading. If that doesn't work,
merging the defaults should be ok.

> } I also wonder if we could make it possible for shell function widgets
> } to specify some sort of default key binding much as is possible for
> } completion widgets.
> 
> The widgets don't really specify their key binding, that's all done by
> compinit when it scans $fpath for #compdef lines.  We could easily have
> another such script that looks for a different #something.  There is
> already #autoload but it doesn't do bindings.

Somehow, I had thought compinit only looked at files named comp* or
_* but apparently not. I still would have considered #autoload as
implying the function was completion related. It seems a bit wasteful
to have two scripts scanning the whole of $fpath and generating caches.
Perhaps we should squeeze it into compinit and accept that it leaves
compinit badly named. Or is it better to somehow factor out that step
and share the results. An alternative might be to have separate *init
functions containing hardcoded lists of widget names so you might have a
zleviminit that would autoload a fixed list of widgets.

The patch below contains documentation to the vi default keys change I
proposed before. I've added in the removal of ^X in viins and the g~~
binding. It took me by surprise to see that redo is not bound by default
in emacs mode. Seems you have to reverse the direction of undo in emacs,
right? I can't remember any complaints about the lack of strict emacs
compatibility leading to lost changes there. I'm inclined to go ahead
with the vi mode undo change: vim converts probably outnumber vi purists
among zsh vi mode users.

Oliver

diff --git a/Doc/Zsh/zle.yo b/Doc/Zsh/zle.yo
index d49c720..dd8e628 100644
--- a/Doc/Zsh/zle.yo
+++ b/Doc/Zsh/zle.yo
@@ -1073,7 +1073,7 @@ Move backward one word, where a word is defined as a series of
 non-blank characters.
 )
 tindex(vi-backward-blank-word-end)
-item(tt(vi-backward-blank-word-end) (unbound) (unbound) (unbound))(
+item(tt(vi-backward-blank-word-end) (unbound) (gE) (unbound))(
 Move to the end of the previous word, where a word is defined as a
 series of non-blank characters.
 )
@@ -1098,7 +1098,7 @@ item(tt(vi-backward-word) (unbound) (b) (unbound))(
 Move to the beginning of the previous word, vi-style.
 )
 tindex(vi-backward-word-end)
-item(tt(vi-backward-word-end) (unbound) (unbound) (unbound))(
+item(tt(vi-backward-word-end) (unbound) (ge) (unbound))(
 Move to the end of the previous word, vi-style.
 )
 tindex(beginning-of-line)
@@ -1215,7 +1215,7 @@ texinode(History Control)(Modifying Text)(Movement)(Zle Widgets)
 subsect(History Control)
 startitem()
 tindex(beginning-of-buffer-or-history)
-item(tt(beginning-of-buffer-or-history) (ESC-<) (unbound) (unbound))(
+item(tt(beginning-of-buffer-or-history) (ESC-<) (gg) (unbound))(
 Move to the beginning of the buffer, or if already there,
 move to the first event in the history list.
 )
@@ -1728,7 +1728,7 @@ item(tt(vi-open-line-below) (unbound) (o) (unbound))(
 Open a line below the cursor and enter insert mode.
 )
 tindex(vi-oper-swap-case)
-item(tt(vi-oper-swap-case))(
+item(tt(vi-oper-swap-case) (unbound) (g~) (unbound))(
 Read a movement command from the keyboard, and swap
 the case of all characters
 from the cursor position to the endpoint of the movement.
@@ -2286,7 +2286,7 @@ This command is executed when a key sequence that is not bound to any
 command is typed.  By default it beeps.
 )
 tindex(undo)
-item(tt(undo) (^_ ^Xu ^X^U) (unbound) (unbound))(
+item(tt(undo) (^_ ^Xu ^X^U) (u) (unbound))(
 Incrementally undo the last text modification.  When called from a
 user-defined widget, takes an optional argument indicating a previous state
 of the undo history as returned by the tt(UNDO_CHANGE_NO) variable;
@@ -2297,11 +2297,11 @@ insert mode is reverted, the changes having been merged when command mode was
 selected.
 )
 tindex(redo)
-item(tt(redo))(
+item(tt(redo) (unbound) (^R) (unbound))(
 Incrementally redo undone text modifications.
 )
 tindex(vi-undo-change)
-item(tt(vi-undo-change) (unbound) (u) (unbound))(
+item(tt(vi-undo-change) (unbound) (unbound) (unbound))(
 Undo the last text modification.
 If repeated, redo the modification.
 )
@@ -2320,7 +2320,7 @@ following an operator, it forces the subsequent movement command to be
 treated as a line-wise movement.
 )
 tindex(what-cursor-position)
-item(tt(what-cursor-position) (^X=) (unbound) (unbound))(
+item(tt(what-cursor-position) (^X=) (ga) (unbound))(
 Print the character under the cursor, its code as an octal, decimal and
 hexadecimal number, the current cursor position within the buffer and the
 column of the cursor in the current line.
diff --git a/Src/Zle/zle_bindings.c b/Src/Zle/zle_bindings.c
index e3337d0..2ae8c87 100644
--- a/Src/Zle/zle_bindings.c
+++ b/Src/Zle/zle_bindings.c
@@ -278,7 +278,7 @@ int viinsbind[32] = {
     /* ^U */ z_vikillline,
     /* ^V */ z_viquotedinsert,
     /* ^W */ z_vibackwardkillword,
-    /* ^X */ z_selfinsert,
+    /* ^X */ z_undefinedkey,
     /* ^Y */ z_selfinsert,
     /* ^Z */ z_selfinsert,
     /* ^[ */ z_vicmdmode,
diff --git a/Src/Zle/zle_keymap.c b/Src/Zle/zle_keymap.c
index afba592..be02f3a 100644
--- a/Src/Zle/zle_keymap.c
+++ b/Src/Zle/zle_keymap.c
@@ -1373,6 +1373,7 @@ default_bindings(void)
     bindkey(amap, "gE", refthingy(t_vibackwardblankwordend), NULL);
     bindkey(amap, "gg", refthingy(t_beginningofbufferorhistory), NULL);
     bindkey(amap, "g~", refthingy(t_vioperswapcase), NULL);
+    bindkey(amap, "g~~", NULL, "g~g~");
 
     /* emacs mode: arrow keys */ 
     add_cursor_key(emap, TCUPCURSOR, t_uplineorhistory, 'A');


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

end of thread, other threads:[~2014-12-12 16:53 UTC | newest]

Thread overview: 28+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2014-11-17 21:36 PATCH: key bindings, fixes, docs, tests for vi stuff Oliver Kiddle
2014-11-18  8:04 ` Jun T.
2014-11-19  8:48   ` Oliver Kiddle
2014-11-19 15:35     ` Ray Andrews
2014-11-21  0:01   ` Oliver Kiddle
2014-11-21  0:49     ` Bart Schaefer
2014-11-21  1:10       ` Ray Andrews
2014-11-21  5:53         ` Bart Schaefer
2014-11-21 10:35       ` Oliver Kiddle
2014-11-22  6:59         ` Bart Schaefer
2014-12-12 16:47           ` Oliver Kiddle
2014-11-21  1:15     ` Ray Andrews
2014-11-21  2:20       ` Mikael Magnusson
2014-11-21  2:38         ` Ray Andrews
2014-11-21  6:23           ` Bart Schaefer
2014-11-21 17:28             ` trouble with debugging binary Ray Andrews
2014-11-22  4:45               ` Bart Schaefer
2014-11-22  5:27                 ` Ray Andrews
2014-11-22  5:43                 ` Bart Schaefer
2014-11-22 16:49                   ` Ray Andrews
2014-11-22 22:35                     ` Bart Schaefer
2014-11-23  7:58                     ` Lawrence Velázquez
2014-11-23 16:22                       ` Ray Andrews
2014-11-23 18:12                         ` Mikael Magnusson
2014-11-23 18:42                           ` Ray Andrews
2014-11-23 19:01                             ` Mikael Magnusson
2014-11-23 22:30                               ` Ray Andrews
2014-11-21 15:20     ` PATCH: key bindings, fixes, docs, tests for vi stuff Jun T.

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).