Zsh Mailing List Archive
Messages sorted by:
Reverse Date,
Date,
Thread,
Author
PATCH: ignore KEYTIMEOUT for vi operators
- X-seq: zsh-workers 33950
- From: Oliver Kiddle <okiddle@xxxxxxxxxxx>
- To: Zsh workers <zsh-workers@xxxxxxx>
- Subject: PATCH: ignore KEYTIMEOUT for vi operators
- Date: Thu, 11 Dec 2014 00:55:55 +0100
- Dkim-signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=yahoo.co.uk; s=s2048; t=1418255757; bh=J7gyc/cZcy48JrGubRbRuX2UhU3T5N+KR2mZSibPrwo=; h=From:To:Subject:Date:From:Subject; b=Fuk4w6j/1GTrkyU+11UsfBwb6ygZXBwabcLvlAuSgRVr2Ac4pTFW8P06YStS85It6t7f11WVrTCja0CtDh8bBDx+uCxBYewMnYXZiRt+ie7VHLUAybF4iv6k2XHa/GcugXsvOHn+lVO4ZbFwOBS2A105SuoypQfswGysYDy0MZhFtlP7lwOOWH0gIcDzRF5JLS776cFlT+/cIX80g8CXP2H/F1EK713RvcWrnlP50QCQmRXNaMjwTLgM9CDammCoe40mygA8FxAN55HBw+079+agg7Wy5wIDoPSFbkkhVjEi4eME73qCaE+afPdIMg5EHWLETAebzxr9wqNStNNTWg==
- Domainkey-signature: a=rsa-sha1; q=dns; c=nofws; s=s2048; d=yahoo.co.uk; b=kh+Sqfl94TFIPFr2smYKPv0P+XXOdOpFhiqV5Id/3YxalVFzpiAWz9fSRTIyrIgL8bpO+Gu8vOc7cI0jMJS2A3snrEOffVIEZ3ceLeg22dv7kjws+V8EG2wbTTIZX+H21J7PbWka8SayqGefvdLbi1C6WTzKeSnhLKDtqLV0B0v0B1onYdr22thH0UI7cdtyoJiF96Q3Ju0dmA34S0cfa1BOeymGZaWfkxYoWN+zf7mR+Jh2zCQliuM+PP8r+rjR6QCsHeA1lVq2XHB0bZoOb+q/1hIicHsCJCab487lnMZCG4KPdFW+Qb6+ZgO7tfLz7xqw6rYxcEQLnp7Kw1mF0A==;
- List-help: <mailto:zsh-workers-help@zsh.org>
- List-id: Zsh Workers List <zsh-workers.zsh.org>
- List-post: <mailto:zsh-workers@zsh.org>
- Mailing-list: contact zsh-workers-help@xxxxxxx; run by ezmlm
The most common use of KEYTIMEOUT is probably where the prefix is an
escape: extended keys all generate sequences starting with escape and
many emacs bindings involve pressing escape followed by something else.
(or does everyone use Meta?) I previously mentioned perhaps having a
separate ESCTIMEOUT so that I could have that set to a lower value but
after looking closer, I think the following approach is perhaps better.
It turns out that all my other prefixes are vi operators that require a
movement. I have lots of things bound after ^X but as ^X itself is not
bound, KEYTIMEOUT doesn't apply. Given that something like vi-change is
going to hang around waiting for a movement key anyway, it seemed
reasonable to not call vi-change until a key is available allowing
plenty of time to check if a further key might match a different
binding.
I've had to add yet another flag to mark the vi operators. It has to
check for region_active and the virangeflag check is necessary so that
things like the following work:
bindkey -a -s 'g~~' 'g~g~'
That could perhaps be added to the default bindings.
I've also added a note to the documentation about cw actually doing ce
for vi compatibility and that bindkey -a -s cw dwi can be used to
disable that.
No tests which shouldn't be a surprise to anyone following the recent
thread about KEYTIMEOUT in test cases.
There would probably be some sense in KEYTIMEOUT having a lower default
for vi-mode users. Any thoughts on that and on how it could be
implemented without breaking user customisations if bindkey -e/v comes
after KEYTIMEOUT is set.
Oliver
diff --git a/Doc/Zsh/zle.yo b/Doc/Zsh/zle.yo
index f952642..d49c720 100644
--- a/Doc/Zsh/zle.yo
+++ b/Doc/Zsh/zle.yo
@@ -1605,6 +1605,13 @@ Read a movement command from the keyboard, and kill
from the cursor position to the endpoint of the movement.
Then enter insert mode.
If the command is tt(vi-change), change the current line.
+
+For compatibility with vi, if the command is tt(vi-forward-word)
+or tt(vi-forward-blank-word), the whitespace after the word is not
+included. If you prefer the more consistent behaviour with the
+whitespace included use the following key binding:
+
+example(bindkey -a -s cw dwi)
)
tindex(vi-change-eol)
item(tt(vi-change-eol) (unbound) (C) (unbound))(
diff --git a/Src/Zle/iwidgets.list b/Src/Zle/iwidgets.list
index a84d4dd..b41661a 100644
--- a/Src/Zle/iwidgets.list
+++ b/Src/Zle/iwidgets.list
@@ -134,11 +134,11 @@
"vi-backward-blank-word-end", vibackwardblankwordend, 0
"vi-beginning-of-line", vibeginningofline, 0
"vi-caps-lock-panic", vicapslockpanic, ZLE_LASTCOL
-"vi-change", vichange, ZLE_LASTCOL
+"vi-change", vichange, ZLE_LASTCOL | ZLE_VIOPER
"vi-change-eol", vichangeeol, 0
"vi-change-whole-line", vichangewholeline, 0
"vi-cmd-mode", vicmdmode, 0
-"vi-delete", videlete, ZLE_KEEPSUFFIX | ZLE_LASTCOL
+"vi-delete", videlete, ZLE_KEEPSUFFIX | ZLE_LASTCOL | ZLE_VIOPER
"vi-delete-char", videletechar, ZLE_KEEPSUFFIX
"vi-digit-or-beginning-of-line", vidigitorbeginningofline, 0
"vi-down-line-or-history", vidownlineorhistory, ZLE_LINEMOVE
@@ -159,7 +159,7 @@
"vi-goto-mark-line", vigotomarkline, ZLE_LINEMOVE
"vi-history-search-backward", vihistorysearchbackward, 0
"vi-history-search-forward", vihistorysearchforward, 0
-"vi-indent", viindent, ZLE_LASTCOL
+"vi-indent", viindent, ZLE_LASTCOL | ZLE_VIOPER
"vi-insert", viinsert, 0
"vi-insert-bol", viinsertbol, 0
"vi-join", vijoin, 0
@@ -168,7 +168,7 @@
"vi-match-bracket", vimatchbracket, 0
"vi-open-line-above", viopenlineabove, 0
"vi-open-line-below", viopenlinebelow, 0
-"vi-oper-swap-case", vioperswapcase, ZLE_LASTCOL
+"vi-oper-swap-case", vioperswapcase, ZLE_LASTCOL | ZLE_VIOPER
"vi-pound-insert", vipoundinsert, 0
"vi-put-after", viputafter, ZLE_YANKAFTER | ZLE_KEEPSUFFIX
"vi-put-before", viputbefore, ZLE_YANKBEFORE | ZLE_KEEPSUFFIX
@@ -185,9 +185,9 @@
"vi-substitute", visubstitute, 0
"vi-swap-case", viswapcase, ZLE_LASTCOL
"vi-undo-change", viundochange, ZLE_KEEPSUFFIX
-"vi-unindent", viunindent, ZLE_LASTCOL
+"vi-unindent", viunindent, ZLE_LASTCOL | ZLE_VIOPER
"vi-up-line-or-history", viuplineorhistory, ZLE_LINEMOVE
-"vi-yank", viyank, ZLE_LASTCOL
+"vi-yank", viyank, ZLE_LASTCOL | ZLE_VIOPER
"vi-yank-eol", viyankeol, 0
"vi-yank-whole-line", viyankwholeline, 0
"visual-line-mode", visuallinemode, ZLE_MENUCMP | ZLE_LASTCOL
diff --git a/Src/Zle/zle.h b/Src/Zle/zle.h
index a46b52d..3c65290 100644
--- a/Src/Zle/zle.h
+++ b/Src/Zle/zle.h
@@ -207,11 +207,12 @@ struct widget {
#define ZLE_YANKBEFORE (1<<4)
#define ZLE_YANK (ZLE_YANKAFTER | ZLE_YANKBEFORE)
#define ZLE_LINEMOVE (1<<5) /* command is a line-oriented movement */
-#define ZLE_LASTCOL (1<<6) /* command maintains lastcol correctly */
-#define ZLE_KILL (1<<7)
-#define ZLE_KEEPSUFFIX (1<<8) /* DON'T remove added suffix */
-#define ZLE_NOTCOMMAND (1<<9) /* widget should not alter lastcmd */
-#define ZLE_ISCOMP (1<<10) /* usable for new style completion */
+#define ZLE_VIOPER (1<<6) /* widget reads further keys so wait if prefix */
+#define ZLE_LASTCOL (1<<7) /* command maintains lastcol correctly */
+#define ZLE_KILL (1<<8)
+#define ZLE_KEEPSUFFIX (1<<9) /* DON'T remove added suffix */
+#define ZLE_NOTCOMMAND (1<<10) /* widget should not alter lastcmd */
+#define ZLE_ISCOMP (1<<11) /* usable for new style completion */
/* thingies */
diff --git a/Src/Zle/zle_keymap.c b/Src/Zle/zle_keymap.c
index 6957e9f..c72168c 100644
--- a/Src/Zle/zle_keymap.c
+++ b/Src/Zle/zle_keymap.c
@@ -1441,6 +1441,7 @@ getkeymapcmd(Keymap km, Thingy *funcp, char **strp)
Thingy func = t_undefinedkey;
char *str = NULL;
int lastlen = 0, lastc = lastchar;
+ int timeout = 0;
keybuflen = 0;
keybuf[0] = 0;
@@ -1458,7 +1459,7 @@ getkeymapcmd(Keymap km, Thingy *funcp, char **strp)
* argument to bindkey is in the correct form for the locale.
* That's beyond our control.
*/
- while(getkeybuf(!!lastlen) != EOF) {
+ while(getkeybuf(timeout) != EOF) {
char *s;
Thingy f;
int loc = !!localkeymap;
@@ -1477,6 +1478,11 @@ getkeymapcmd(Keymap km, Thingy *funcp, char **strp)
func = f;
str = s;
lastc = lastchar;
+
+ /* can be patient with vi commands that need a motion operator: *
+ * they wait till a key is pressed for the movement anyway */
+ timeout = !(!virangeflag && !region_active && f && f->widget &&
+ f->widget->flags & ZLE_VIOPER);
}
if (!ispfx)
break;
Messages sorted by:
Reverse Date,
Date,
Thread,
Author