diff options
-rw-r--r-- | ChangeLog | 6 | ||||
-rw-r--r-- | Doc/Zsh/zle.yo | 13 | ||||
-rw-r--r-- | Src/Zle/zle_keymap.c | 42 |
3 files changed, 57 insertions, 4 deletions
diff --git a/ChangeLog b/ChangeLog index 53c8559b7..403340de7 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2001-04-19 Peter Stephenson <pws@pwstephenson.fsnet.co.uk> + + * 14046: Doc/Zle/zle.yo, Src/Zle/zle_keymap.c: bindkey -rp removes + bindings with given prefix; minor bugfix for length of prefix with + bindkey -p. + 2001-04-19 Clint Adams <schizo@debian.org> * unposted: configure.in: make sure all the libraries are diff --git a/Doc/Zsh/zle.yo b/Doc/Zsh/zle.yo index 87e5182b3..46d604a0c 100644 --- a/Doc/Zsh/zle.yo +++ b/Doc/Zsh/zle.yo @@ -175,7 +175,20 @@ Only keys that are unbound or bound to tt(self-insert) are affected. item(tt(-r) var(in-string) ...)( Unbind the specified var(in-string)s in the selected keymap. This is exactly equivalent to binding the strings to tt(undefined-key). + When tt(-R) is also used, interpret the var(in-string)s as ranges. + +When tt(-p) is also used, the var(in-string)s specify prefixes. Any +binding that has the given var(in-string) as a prefix, not including the +binding for the var(in-string) itself, if any, will be removed. For +example, + +example(bindkey -rpM viins '^[') + +will remove all bindings in the vi-insert keymap beginning with an escape +character (probably cursor keys), but leave the binding for the escape +character itself (probably tt(vi-cmd-mode)). This is incompatible with the +option tt(-R). ) item(tt(-s) var(in-string out-string) ...)( Bind each var(in-string) to each var(out-string). diff --git a/Src/Zle/zle_keymap.c b/Src/Zle/zle_keymap.c index 9a485a506..f820a758f 100644 --- a/Src/Zle/zle_keymap.c +++ b/Src/Zle/zle_keymap.c @@ -90,6 +90,14 @@ struct bindstate { int prefixlen; }; +/* This structure is used when scanning for prefix bindings to remove */ + +struct remprefstate { + Keymap km; + char *prefix; + int prefixlen; +}; + #define BS_LIST (1<<0) #define BS_ALL (1<<1) @@ -836,6 +844,19 @@ bin_bindkey_bind(char *name, char *kmname, Keymap km, char **argv, char *ops, ch zwarnnam(name, "keymap `%s' is protected", kmname, 0); return 1; } + if (func == 'r' && ops['p']) { + char *useq, *bseq; + int len; + struct remprefstate rps; + rps.km = km; + while ((useq = *argv++)) { + bseq = getkeystring(useq, &len, 2, NULL); + rps.prefix = metafy(bseq, len, META_USEHEAP); + rps.prefixlen = strlen(rps.prefix); + scankeymap(km, 0, scanremoveprefix, &rps); + } + return 0; + } do { char *useq = *argv, *bseq, *seq, *str; int len; @@ -880,6 +901,20 @@ bin_bindkey_bind(char *name, char *kmname, Keymap km, char **argv, char *ops, ch return ret; } +/* Remove bindings for key sequences which have the given (proper) prefix. */ + +/**/ +static void +scanremoveprefix(char *seq, Thingy bind, char *str, void *magic) +{ + struct remprefstate *rps = magic; + + if (strncmp(seq, rps->prefix, rps->prefixlen) || !seq[rps->prefixlen]) + return; + + bindkey(rps->km, seq, refthingy(t_undefinedkey), NULL); +} + /* List key bindings. If an argument is given, list just that one * * binding, otherwise list the entire keymap. If the -L option is * * given, list in the form of bindkey commands. */ @@ -913,6 +948,7 @@ bin_bindkey_list(char *name, char *kmname, Keymap km, char **argv, char *ops, ch } bs.prefix = getkeystring(argv[0], &bs.prefixlen, 2, NULL); bs.prefix = metafy(bs.prefix, bs.prefixlen, META_HREALLOC); + bs.prefixlen = strlen(bs.prefix); } else { bs.prefix = NULL; bs.prefixlen = 0; @@ -1067,11 +1103,9 @@ add_cursor_key(Keymap km, int tccode, Thingy thingy, int defchar) /* * Sanity checking. If the cursor key is zero-length (unlikely, * but this is termcap we're talking about), or it's a single - * character which is already bound, then we don't bind it. + * character, then we don't bind it. */ - if (!buf[0] || (!buf[1] && km->first[STOUC(buf[0])] != t_undefinedkey)) - ok = 0; - else + if (buf[0] && buf[1] && (buf[0] != Meta || buf[2])) ok = 1; } if (!ok) { |