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

Re: one time in 20 error



On 29 Nov, Roman Perepelitsa wrote:
> I have the following in my .zshrc:
>
>     function skip-csi-sequence() {
>      local key
>      while read -sk key && (( $((#key)) < 0x40 || $((#key)) > 0x7E )); do
>        # empty body
>      done
>     }
>
>     zle -N skip-csi-sequence
>     bindkey '\e[' skip-csi-sequence
>
> With this binding a buggy script that leaks mouse events into zle
> won't have any effect.

This is a nice idea. I've occasionally had unwanted effects from
unintentionally hitting a function key. I thought I'd try this in C.

After testing this, I'm inclined to think it would be better to special
case the CSI sequence in getkeymapcmd() instead. Currently, you would
need to bind this in every local keymap because most local keymaps will
include a binding starting with the \e[ sequence. It is also common for
Alt-[ to generate \e[. Binding that would override the skip-csi-sequence
binding but we could discern between the two based on KEYTIMEOUT. Any
other thoughts on this. Or objections to such an approach? Are there
terminals out there that eschew CSI sequences and for which such special
handling could be problematic? Is anyone especially attached to the
current behaviour where unbound function keys and mouse movements cause
chaos?

I notice that bash has a skip-csi-sequence widget but leaves it
disabled by default. Would be interesting ot know why.

The patch below tries the widget approach. Rather than look for the
termination character, I thought it better to bail out given any
out-of-range parameter byte or KEYTIMEOUT being exceeded. As yet, I'm
not planning to apply this.

Oliver

diff --git a/Src/Zle/iwidgets.list b/Src/Zle/iwidgets.list
index c95c7a491..8d1b64e58 100644
--- a/Src/Zle/iwidgets.list
+++ b/Src/Zle/iwidgets.list
@@ -112,6 +112,7 @@
 "self-insert-unmeta", selfinsertunmeta, ZLE_MENUCMP | ZLE_KEEPSUFFIX
 "send-break", sendbreak, 0
 "set-mark-command", setmarkcommand, ZLE_MENUCMP | ZLE_KEEPSUFFIX | ZLE_LASTCOL
+"skip-csi-sequence", skipcsisequence, ZLE_MENUCMP | ZLE_KEEPSUFFIX | ZLE_LASTCOL
 "split-undo", splitundo, ZLE_MENUCMP | ZLE_KEEPSUFFIX | ZLE_LASTCOL | ZLE_NOTCOMMAND
 "spell-word", spellword, 0
 "set-local-history", setlocalhistory, ZLE_LASTCOL
diff --git a/Src/Zle/zle_keymap.c b/Src/Zle/zle_keymap.c
index d90838f03..737d3cd72 100644
--- a/Src/Zle/zle_keymap.c
+++ b/Src/Zle/zle_keymap.c
@@ -1430,6 +1430,11 @@ default_bindings(void)
     bindkey(emap, "\30\30", refthingy(t_exchangepointandmark), NULL);
     bindkey(emap, "\30=",   refthingy(t_whatcursorposition), NULL);
 
+    /* skip unbound CSI sequence in all keymaps */
+    bindkey(emap, "\33[", refthingy(t_skipcsisequence), NULL);
+    bindkey(vmap, "\33[", refthingy(t_skipcsisequence), NULL);
+    bindkey(amap, "\33[", refthingy(t_skipcsisequence), NULL);
+
     /* bracketed paste applicable to all keymaps */
     bindkey(emap, "\33[200~", refthingy(t_bracketedpaste), NULL);
     bindkey(vmap, "\33[200~", refthingy(t_bracketedpaste), NULL);
diff --git a/Src/Zle/zle_misc.c b/Src/Zle/zle_misc.c
index eba28d1ec..1b996fb8a 100644
--- a/Src/Zle/zle_misc.c
+++ b/Src/Zle/zle_misc.c
@@ -152,6 +152,19 @@ selfinsertunmeta(char **args)
     return selfinsert(args);
 }
 
+
+/**/
+mod_export int
+skipcsisequence(char **args)
+{
+    int next, timeout;
+    do {
+	next = getbyte(1L, &timeout, 1);
+    } while (!timeout && next >= 0x20 && next <= 0x3f);
+
+    return 1;
+}
+
 /**/
 int
 deletechar(char **args)




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