2 * zle_keymap.c - keymaps and key bindings
4 * This file is part of zsh, the Z shell.
6 * Copyright (c) 1992-1997 Paul Falstad
9 * Permission is hereby granted, without written agreement and without
10 * license or royalty fees, to use, copy, modify, and distribute this
11 * software and to distribute modified versions of this software for any
12 * purpose, provided that the above copyright notice and the following
13 * two paragraphs appear in all copies of this software.
15 * In no event shall Paul Falstad or the Zsh Development Group be liable
16 * to any party for direct, indirect, special, incidental, or consequential
17 * damages arising out of the use of this software and its documentation,
18 * even if Paul Falstad and the Zsh Development Group have been advised of
19 * the possibility of such damage.
21 * Paul Falstad and the Zsh Development Group specifically disclaim any
22 * warranties, including, but not limited to, the implied warranties of
23 * merchantability and fitness for a particular purpose. The software
24 * provided hereunder is on an "as is" basis, and Paul Falstad and the
25 * Zsh Development Group have no obligation to provide maintenance,
26 * support, updates, enhancements, or modifications.
35 * There is a hash table of keymap names. Each name just points to a keymap.
36 * More than one name may point to the same keymap.
38 * Each keymap consists of a table of bindings for each character, and a
39 * hash table of multi-character key bindings. The keymap has no individual
40 * name, but maintains a reference count.
42 * In a keymap's table of initial bindings, each character is either bound to
43 * a thingy, or is a prefix (in which case NULL is stored). Those prefix
44 * entries are matched by more complex entries in the multi-character
45 * binding hash table. Each entry in this hash table (which is indexed by
46 * metafied key sequence) either has a normal thingy binding or a string to
47 * send (in which case the NULL thingy is used). Each entry also has a count
48 * of other entries for which it is a prefix.
51 typedef struct keymapname
*KeymapName
;
52 typedef struct key
*Key
;
55 HashNode next
; /* next in the hash chain */
56 char *nam
; /* name of the keymap */
57 int flags
; /* various flags (see below) */
58 Keymap keymap
; /* the keymap itsef */
61 #define KMN_IMMORTAL (1<<1)
64 Thingy first
[256]; /* base binding of each character */
65 HashTable multi
; /* multi-character bindings */
66 int flags
; /* various flags (see below) */
67 int rc
; /* reference count */
70 #define KM_IMMUTABLE (1<<1)
73 HashNode next
; /* next in hash chain */
74 char *nam
; /* key sequence (metafied) */
75 Thingy bind
; /* binding of this key sequence */
76 char *str
; /* string for send-string (metafied) */
77 int prefixct
; /* number of sequences for which this is a prefix */
80 /* This structure is used when listing keymaps. */
93 /* This structure is used when scanning for prefix bindings to remove */
101 #define BS_LIST (1<<0)
102 #define BS_ALL (1<<1)
104 /* local functions */
106 #include "zle_keymap.pro"
108 /* currently selected keymap, and its name */
111 Keymap curkeymap
, localkeymap
;
115 /* the hash table of keymap names */
118 mod_export HashTable keymapnamtab
;
120 /* key sequence reading data */
125 static int keybuflen
, keybufsz
= 20;
127 /* last command executed with execute-named-command */
129 static Thingy lastnamed
;
131 /**********************************/
132 /* hashtable management functions */
133 /**********************************/
137 createkeymapnamtab(void)
139 keymapnamtab
= newhashtable(7, "keymapnamtab", NULL
);
141 keymapnamtab
->hash
= hasher
;
142 keymapnamtab
->emptytable
= emptyhashtable
;
143 keymapnamtab
->filltable
= NULL
;
144 keymapnamtab
->cmpnodes
= strcmp
;
145 keymapnamtab
->addnode
= addhashnode
;
146 keymapnamtab
->getnode
= gethashnode2
;
147 keymapnamtab
->getnode2
= gethashnode2
;
148 keymapnamtab
->removenode
= removehashnode
;
149 keymapnamtab
->disablenode
= NULL
;
150 keymapnamtab
->enablenode
= NULL
;
151 keymapnamtab
->freenode
= freekeymapnamnode
;
152 keymapnamtab
->printnode
= NULL
;
157 makekeymapnamnode(Keymap keymap
)
159 KeymapName kmn
= (KeymapName
) zshcalloc(sizeof(*kmn
));
161 kmn
->keymap
= keymap
;
167 freekeymapnamnode(HashNode hn
)
169 KeymapName kmn
= (KeymapName
) hn
;
172 unrefkeymap(kmn
->keymap
);
173 zfree(kmn
, sizeof(*kmn
));
178 newkeytab(char *kmname
)
180 HashTable ht
= newhashtable(19,
181 kmname
? dyncat("keytab:", kmname
) : "keytab:", NULL
);
184 ht
->emptytable
= emptyhashtable
;
185 ht
->filltable
= NULL
;
186 ht
->cmpnodes
= strcmp
;
187 ht
->addnode
= addhashnode
;
188 ht
->getnode
= gethashnode2
;
189 ht
->getnode2
= gethashnode2
;
190 ht
->removenode
= removehashnode
;
191 ht
->disablenode
= NULL
;
192 ht
->enablenode
= NULL
;
193 ht
->freenode
= freekeynode
;
194 ht
->printnode
= NULL
;
201 makekeynode(Thingy t
, char *str
)
203 Key k
= (Key
) zshcalloc(sizeof(*k
));
212 freekeynode(HashNode hn
)
217 unrefthingy(k
->bind
);
219 zfree(k
, sizeof(*k
));
222 /**************************/
223 /* main keymap operations */
224 /**************************/
226 static HashTable copyto
;
230 newkeymap(Keymap tocopy
, char *kmname
)
232 Keymap km
= zshcalloc(sizeof(*km
));
236 km
->multi
= newkeytab(kmname
);
239 km
->first
[i
] = refthingy(tocopy
->first
[i
]);
241 scanhashtable(tocopy
->multi
, 0, 0, 0, scancopykeys
, 0);
244 km
->first
[i
] = refthingy(t_undefinedkey
);
251 scancopykeys(HashNode hn
, UNUSED(int flags
))
254 Key kn
= zalloc(sizeof(*k
));
256 memcpy(kn
, k
, sizeof(*k
));
258 kn
->str
= ztrdup(k
->str
);
259 copyto
->addnode(copyto
, ztrdup(k
->nam
), kn
);
264 deletekeymap(Keymap km
)
268 deletehashtable(km
->multi
);
270 unrefthingy(km
->first
[i
]);
271 zfree(km
, sizeof(*km
));
274 static Keymap skm_km
;
276 static KeyScanFunc skm_func
;
277 static void *skm_magic
;
281 scankeymap(Keymap km
, int sort
, KeyScanFunc func
, void *magic
)
286 skm_last
= sort
? -1 : 255;
289 scanhashtable(km
->multi
, sort
, 0, 0, scankeys
, 0);
292 while(skm_last
< 255) {
294 if(km
->first
[skm_last
] && km
->first
[skm_last
] != t_undefinedkey
) {
296 metafy(m
, 1, META_NOALLOC
);
297 func(m
, km
->first
[skm_last
], NULL
, magic
);
304 scankeys(HashNode hn
, UNUSED(int flags
))
307 int f
= k
->nam
[0] == Meta
? STOUC(k
->nam
[1])^32 : STOUC(k
->nam
[0]);
310 while(skm_last
< f
) {
312 if(skm_km
->first
[skm_last
] &&
313 skm_km
->first
[skm_last
] != t_undefinedkey
) {
315 metafy(m
, 1, META_NOALLOC
);
316 skm_func(m
, skm_km
->first
[skm_last
], NULL
, skm_magic
);
319 skm_func(k
->nam
, k
->bind
, k
->str
, skm_magic
);
322 /**************************/
323 /* keymap name operations */
324 /**************************/
328 openkeymap(char *name
)
330 KeymapName n
= (KeymapName
) keymapnamtab
->getnode(keymapnamtab
, name
);
331 return n
? n
->keymap
: NULL
;
336 unlinkkeymap(char *name
, int ignm
)
338 KeymapName n
= (KeymapName
) keymapnamtab
->getnode(keymapnamtab
, name
);
341 if(!ignm
&& (n
->flags
& KMN_IMMORTAL
))
343 keymapnamtab
->freenode(keymapnamtab
->removenode(keymapnamtab
, name
));
349 linkkeymap(Keymap km
, char *name
, int imm
)
351 KeymapName n
= (KeymapName
) keymapnamtab
->getnode(keymapnamtab
, name
);
353 if(n
->flags
& KMN_IMMORTAL
)
357 unrefkeymap(n
->keymap
);
360 n
= makekeymapnamnode(km
);
362 n
->flags
|= KMN_IMMORTAL
;
363 keymapnamtab
->addnode(keymapnamtab
, ztrdup(name
), n
);
370 void refkeymap(Keymap km
)
376 void unrefkeymap(Keymap km
)
382 /* Select a keymap as the current ZLE keymap. Can optionally fall back *
383 * on the guaranteed safe keymap if it fails. */
387 selectkeymap(char *name
, int fb
)
389 Keymap km
= openkeymap(name
);
392 char *nm
= nicedup(name
, 0);
393 char *msg
= tricat("No such keymap `", nm
, "'");
400 km
= openkeymap(name
= ".safe");
402 if(name
!= curkeymapname
) {
403 char *oname
= curkeymapname
;
406 curkeymapname
= ztrdup(name
);
408 if (oname
&& zleactive
&& strcmp(oname
, curkeymapname
) &&
409 (chgthingy
= rthingy_nocreate("zle-keymap-select"))) {
411 int saverrflag
= errflag
, savretflag
= retflag
;
414 errflag
= retflag
= 0;
415 execzlefunc(chgthingy
, args
, 1);
416 unrefthingy(chgthingy
);
417 errflag
= saverrflag
;
418 retflag
= savretflag
;
426 /* Select a local key map. */
430 selectlocalmap(Keymap m
)
435 /* Reopen the currently selected keymap, in case it got deleted. This *
436 * should be called after doing anything that might have run an *
437 * arbitrary user-specified command. */
443 selectkeymap(curkeymapname
, 1);
446 /******************************/
447 /* operations on key bindings */
448 /******************************/
450 /* Add/delete/change a keybinding in some keymap. km is the keymap to be *
451 * altered. seq is the metafied key sequence whose binding is to change. *
452 * bind is the thingy to which the key sequence is to be bound. For *
453 * send-string, bind is NULL and str is the metafied key sequence to push *
454 * back onto the input. */
458 bindkey(Keymap km
, char *seq
, Thingy bind
, char *str
)
461 int f
= seq
[0] == Meta
? STOUC(seq
[1])^32 : STOUC(seq
[0]);
464 if(km
->flags
& KM_IMMUTABLE
)
468 if(!bind
|| ztrlen(seq
) > 1) {
469 /* key needs to become a prefix if isn't one already */
473 metafy(fs
, 1, META_NOALLOC
);
474 km
->multi
->addnode(km
->multi
, ztrdup(fs
),
475 makekeynode(km
->first
[f
], NULL
));
478 k
= (Key
) km
->multi
->getnode(km
->multi
, seq
);
480 /* If the sequence is a prefix entry only due to being *
481 * a send-string binding, we can remove that entry. */
483 k
= (Key
) km
->multi
->getnode(km
->multi
, seq
);
485 km
->multi
->freenode(km
->multi
->removenode(km
->multi
, seq
));
489 unrefthingy(km
->first
[f
]);
490 /* Just replace the single-character binding. */
496 ptr
= strchr(buf
, 0);
497 if(bind
== t_undefinedkey
) {
500 unrefthingy(k
->bind
);
501 k
->bind
= t_undefinedkey
;
503 while(!k
->prefixct
&& k
->bind
== t_undefinedkey
) {
504 km
->multi
->freenode(km
->multi
->removenode(km
->multi
, buf
));
508 k
= (Key
) km
->multi
->getnode(km
->multi
, buf
);
510 if(!k
->prefixct
&& k
->bind
&&
511 (!buf
[1] || (buf
[0] == Meta
&& !buf
[2]))) {
512 km
->first
[f
] = refthingy(k
->bind
);
513 km
->multi
->freenode(km
->multi
->removenode(km
->multi
, buf
));
522 km
->multi
->addnode(km
->multi
, ztrdup(buf
), makekeynode(bind
, ztrdup(str
)));
525 if(ptr
> buf
&& ptr
[-1] == Meta
)
527 k
= (Key
) km
->multi
->getnode(km
->multi
, buf
);
529 km
->multi
->addnode(km
->multi
, ztrdup(buf
),
530 k
= makekeynode(refthingy(t_undefinedkey
), NULL
));
534 unrefthingy(k
->bind
);
537 k
->str
= bind
? NULL
: ztrdup(str
);
544 /* Look up a key binding. The binding is returned. In the case of a *
545 * send-string, NULL is returned and *strp is modified to point to the *
546 * metafied string of characters to be pushed back. */
550 keybind(Keymap km
, char *seq
, char **strp
)
554 if(ztrlen(seq
) == 1) {
555 int f
= seq
[0] == Meta
? STOUC(seq
[1])^32 : STOUC(seq
[0]);
556 Thingy bind
= km
->first
[f
];
561 k
= (Key
) km
->multi
->getnode(km
->multi
, seq
);
563 return t_undefinedkey
;
568 /* Check whether a key sequence is a prefix of a longer bound sequence. *
569 * One oddity: if *nothing* in the keymap is bound, this returns true *
570 * for the empty sequence, even though this is not strictly accurate. */
574 keyisprefix(Keymap km
, char *seq
)
580 if(ztrlen(seq
) == 1) {
581 int f
= seq
[0] == Meta
? STOUC(seq
[1])^32 : STOUC(seq
[0]);
586 k
= (Key
) km
->multi
->getnode(km
->multi
, seq
);
587 return k
&& k
->prefixct
;
590 /*******************/
591 /* bindkey builtin */
592 /*******************/
595 * THE BINDKEY BUILTIN
597 * Keymaps can be specified to bindkey in the following ways:
599 * -e select "emacs", also link it to "main"
600 * -v select "viins", also link it to "main"
602 * -M first argument gives map name
605 * These operations cannot have a keymap selected in the normal way:
607 * -l list all the keymap names
608 * -d delete all keymaps and reset to the default state (no arguments)
609 * -D delete named keymaps
610 * -A link the two named keymaps (2 arguments)
611 * -N create new empty keymap (1 argument)
612 * -N create new keymap, copying the second named keymap (2 arguments)
616 * -m add the meta bindings to the selected keymap (no arguments)
617 * -r unbind each named string in the selected keymap
618 * -s bind send-strings in the selected keymap (2+ arguments)
619 * bind commands in the selected keymap (2+ arguments)
620 * display one binding in the selected keymap (1 argument)
621 * display the entire selected keymap (no arguments)
623 * There is an exception that the entire keymap display will not be performed
624 * if the -e or -v options were used.
628 * -L do listings in the form of bindkey commands
629 * -R for the binding operations, accept ranges instead of sequences
634 bin_bindkey(char *name
, char **argv
, Options ops
, UNUSED(int func
))
639 int (*func
) _((char *, char *, Keymap
, char **, Options
, char));
642 { 'l', 0, bin_bindkey_lsmaps
, 0, 0 },
643 { 'd', 0, bin_bindkey_delall
, 0, 0 },
644 { 'D', 0, bin_bindkey_del
, 1, -1 },
645 { 'A', 0, bin_bindkey_link
, 2, 2 },
646 { 'N', 0, bin_bindkey_new
, 1, 2 },
647 { 'm', 1, bin_bindkey_meta
, 0, 0 },
648 { 'r', 1, bin_bindkey_bind
, 1, -1 },
649 { 's', 1, bin_bindkey_bind
, 2, -1 },
650 { 0, 1, bin_bindkey_bind
, 0, -1 },
652 struct opn
const *op
, *opp
;
657 /* select operation and ensure no clashing arguments */
658 for(op
= opns
; op
->o
&& !OPT_ISSET(ops
,STOUC(op
->o
)); op
++) ;
660 for(opp
= op
; (++opp
)->o
; )
661 if(OPT_ISSET(ops
,STOUC(opp
->o
))) {
662 zwarnnam(name
, "incompatible operation selection options");
665 n
= OPT_ISSET(ops
,'e') + OPT_ISSET(ops
,'v') +
666 OPT_ISSET(ops
,'a') + OPT_ISSET(ops
,'M');
668 zwarnnam(name
, "keymap cannot be selected with -%c", op
->o
);
672 zwarnnam(name
, "incompatible keymap selection options");
676 /* keymap selection */
678 if(OPT_ISSET(ops
,'e'))
680 else if(OPT_ISSET(ops
,'v'))
682 else if(OPT_ISSET(ops
,'a'))
684 else if(OPT_ISSET(ops
,'M')) {
685 kmname
= OPT_ARG(ops
,'M');
688 km
= openkeymap(kmname
);
690 zwarnnam(name
, "no such keymap `%s'", kmname
);
693 if(OPT_ISSET(ops
,'e') || OPT_ISSET(ops
,'v'))
694 linkkeymap(km
, "main", 0);
700 /* listing is a special case */
701 if(!op
->o
&& (!argv
[0] || !argv
[1])) {
702 if(OPT_ISSET(ops
,'e') || OPT_ISSET(ops
,'v'))
704 return bin_bindkey_list(name
, kmname
, km
, argv
, ops
, op
->o
);
707 /* check number of arguments */
708 for(n
= 0; argv
[n
]; n
++) ;
710 zwarnnam(name
, "not enough arguments for -%c", op
->o
);
712 } else if(op
->max
!= -1 && n
> op
->max
) {
713 zwarnnam(name
, "too many arguments for -%c", op
->o
);
717 /* pass on the work to the operation function */
718 return op
->func(name
, kmname
, km
, argv
, ops
, op
->o
);
721 /* list the available keymaps */
725 bin_bindkey_lsmaps(UNUSED(char *name
), UNUSED(char *kmname
), UNUSED(Keymap km
), UNUSED(char **argv
), Options ops
, UNUSED(char func
))
727 scanhashtable(keymapnamtab
, 1, 0, 0, scanlistmaps
, OPT_ISSET(ops
,'L'));
733 scanlistmaps(HashNode hn
, int list
)
735 KeymapName n
= (KeymapName
) hn
;
738 fputs("bindkey -N ", stdout
);
740 fputs("-- ", stdout
);
741 quotedzputs(n
->nam
, stdout
);
743 nicezputs(n
->nam
, stdout
);
747 /* reset all keymaps to the default state */
751 bin_bindkey_delall(UNUSED(char *name
), UNUSED(char *kmname
), UNUSED(Keymap km
), UNUSED(char **argv
), UNUSED(Options ops
), UNUSED(char func
))
753 keymapnamtab
->emptytable(keymapnamtab
);
758 /* delete named keymaps */
762 bin_bindkey_del(char *name
, UNUSED(char *kmname
), UNUSED(Keymap km
), char **argv
, UNUSED(Options ops
), UNUSED(char func
))
767 int r
= unlinkkeymap(*argv
, 0);
769 zwarnnam(name
, "keymap name `%s' is protected", *argv
);
771 zwarnnam(name
, "no such keymap `%s'", *argv
);
777 /* link named keymaps */
781 bin_bindkey_link(char *name
, UNUSED(char *kmname
), Keymap km
, char **argv
, UNUSED(Options ops
), UNUSED(char func
))
783 km
= openkeymap(argv
[0]);
785 zwarnnam(name
, "no such keymap `%s'", argv
[0]);
787 } else if(linkkeymap(km
, argv
[1], 0)) {
788 zwarnnam(name
, "keymap name `%s' is protected", argv
[1]);
794 /* create a new keymap */
798 bin_bindkey_new(char *name
, UNUSED(char *kmname
), Keymap km
, char **argv
, UNUSED(Options ops
), UNUSED(char func
))
800 KeymapName kmn
= (KeymapName
) keymapnamtab
->getnode(keymapnamtab
, argv
[0]);
802 if(kmn
&& (kmn
-> flags
& KMN_IMMORTAL
)) {
803 zwarnnam(name
, "keymap name `%s' is protected", argv
[0]);
807 km
= openkeymap(argv
[1]);
809 zwarnnam(name
, "no such keymap `%s'", argv
[0]);
814 linkkeymap(newkeymap(km
, argv
[0]), argv
[0], 0);
818 /* Add standard meta bindings to a keymap. Only sequences currently either *
819 * unbound or bound to self-insert are affected. Note that the use of *
820 * bindkey() is quite necessary: if this function were to go through the *
821 * km->first table itself, it would miss any prefix sequences that should *
826 bin_bindkey_meta(char *name
, char *kmname
, Keymap km
, UNUSED(char **argv
), UNUSED(Options ops
), UNUSED(char func
))
832 if(km
->flags
& KM_IMMUTABLE
) {
833 zwarnnam(name
, "keymap `%s' is protected", kmname
);
836 #ifdef MULTIBYTE_SUPPORT
837 zwarnnam(name
, "warning: `bindkey -m' disables multibyte support");
839 for(i
= 128; i
< 256; i
++)
840 if(metabind
[i
- 128] != z_undefinedkey
) {
842 metafy(m
, 1, META_NOALLOC
);
843 fn
= keybind(km
, m
, &str
);
844 if(fn
== t_selfinsert
|| fn
== t_undefinedkey
)
845 bindkey(km
, m
, refthingy(Th(metabind
[i
- 128])), NULL
);
850 /* Change key bindings. func can be: *
851 * 'r' bind sequences to undefined-key *
852 * 's' bind sequneces to specified send-strings *
853 * 0 bind sequences to specified functions *
854 * If the -R option is used, bind to key ranges *
855 * instead of single key sequences. */
859 bin_bindkey_bind(char *name
, char *kmname
, Keymap km
, char **argv
, Options ops
, char func
)
863 if(!func
|| func
== 's') {
866 for(a
= argv
+2; *a
; a
++)
868 zwarnnam(name
, "even number of arguments required");
872 if(km
->flags
& KM_IMMUTABLE
) {
873 zwarnnam(name
, "keymap `%s' is protected", kmname
);
876 if (func
== 'r' && OPT_ISSET(ops
,'p')) {
879 struct remprefstate rps
;
881 while ((useq
= *argv
++)) {
882 bseq
= getkeystring(useq
, &len
, GETKEYS_BINDKEY
, NULL
);
883 rps
.prefix
= metafy(bseq
, len
, META_USEHEAP
);
884 rps
.prefixlen
= strlen(rps
.prefix
);
885 scankeymap(km
, 0, scanremoveprefix
, &rps
);
890 char *useq
= *argv
, *bseq
, *seq
, *str
;
895 fn
= refthingy(t_undefinedkey
);
897 } else if(func
== 's') {
898 str
= getkeystring(*++argv
, &len
, GETKEYS_BINDKEY
, NULL
);
900 str
= metafy(str
, len
, META_HREALLOC
);
902 fn
= rthingy(*++argv
);
905 bseq
= getkeystring(useq
, &len
, GETKEYS_BINDKEY
, NULL
);
906 seq
= metafy(bseq
, len
, META_USEHEAP
);
907 if(OPT_ISSET(ops
,'R')) {
911 if(len
< 2 || len
> 2 + (bseq
[1] == '-') ||
912 (first
= STOUC(bseq
[0])) > (last
= STOUC(bseq
[len
- 1]))) {
913 zwarnnam(name
, "malformed key range `%s'", useq
);
916 for(; first
<= last
; first
++) {
918 metafy(m
, 1, META_NOALLOC
);
919 bindkey(km
, m
, refthingy(fn
), str
);
924 if(bindkey(km
, seq
, fn
, str
)) {
925 zwarnnam(name
, "cannot bind to an empty key sequence");
934 /* Remove bindings for key sequences which have the given (proper) prefix. */
938 scanremoveprefix(char *seq
, UNUSED(Thingy bind
), UNUSED(char *str
), void *magic
)
940 struct remprefstate
*rps
= magic
;
942 if (strncmp(seq
, rps
->prefix
, rps
->prefixlen
) || !seq
[rps
->prefixlen
])
945 bindkey(rps
->km
, seq
, refthingy(t_undefinedkey
), NULL
);
948 /* List key bindings. If an argument is given, list just that one *
949 * binding, otherwise list the entire keymap. If the -L option is *
950 * given, list in the form of bindkey commands. */
954 bin_bindkey_list(char *name
, char *kmname
, Keymap km
, char **argv
, Options ops
, UNUSED(char func
))
958 bs
.flags
= OPT_ISSET(ops
,'L') ? BS_LIST
: 0;
960 if(argv
[0] && !OPT_ISSET(ops
,'p')) {
964 seq
= getkeystring(argv
[0], &len
, GETKEYS_BINDKEY
, NULL
);
965 seq
= metafy(seq
, len
, META_HREALLOC
);
967 bs
.firstseq
= bs
.lastseq
= seq
;
968 bs
.bind
= keybind(km
, seq
, &bs
.str
);
973 /* empty prefix is equivalent to no prefix */
974 if (OPT_ISSET(ops
,'p') && (!argv
[0] || argv
[0][0])) {
976 zwarnnam(name
, "option -p requires a prefix string");
979 bs
.prefix
= getkeystring(argv
[0], &bs
.prefixlen
, GETKEYS_BINDKEY
,
981 bs
.prefix
= metafy(bs
.prefix
, bs
.prefixlen
, META_HREALLOC
);
982 bs
.prefixlen
= strlen(bs
.prefix
);
987 bs
.firstseq
= ztrdup("");
988 bs
.lastseq
= ztrdup("");
989 bs
.bind
= t_undefinedkey
;
991 scankeymap(km
, 1, scanbindlist
, &bs
);
1001 scanbindlist(char *seq
, Thingy bind
, char *str
, void *magic
)
1003 struct bindstate
*bs
= magic
;
1005 if (bs
->prefixlen
&&
1006 (strncmp(seq
, bs
->prefix
, bs
->prefixlen
) || !seq
[bs
->prefixlen
]))
1009 if(bind
== bs
->bind
&& (bind
|| !strcmp(str
, bs
->str
)) &&
1010 ztrlen(seq
) == 1 && ztrlen(bs
->lastseq
) == 1) {
1011 int l
= bs
->lastseq
[1] ?
1012 STOUC(bs
->lastseq
[1]) ^ 32 : STOUC(bs
->lastseq
[0]);
1013 int t
= seq
[1] ? STOUC(seq
[1]) ^ 32 : STOUC(seq
[0]);
1016 zsfree(bs
->lastseq
);
1017 bs
->lastseq
= ztrdup(seq
);
1022 zsfree(bs
->firstseq
);
1023 bs
->firstseq
= ztrdup(seq
);
1024 zsfree(bs
->lastseq
);
1025 bs
->lastseq
= ztrdup(seq
);
1032 bindlistout(struct bindstate
*bs
)
1036 if(bs
->bind
== t_undefinedkey
&& !(bs
->flags
& BS_ALL
))
1038 range
= strcmp(bs
->firstseq
, bs
->lastseq
);
1039 if(bs
->flags
& BS_LIST
) {
1042 fputs("bindkey ", stdout
);
1044 fputs("-R ", stdout
);
1046 fputs("-s ", stdout
);
1047 if(!strcmp(bs
->kmname
, "main"))
1049 else if(!strcmp(bs
->kmname
, "vicmd"))
1050 fputs("-a ", stdout
);
1052 fputs("-M ", stdout
);
1053 quotedzputs(bs
->kmname
, stdout
);
1057 if(nodash
&& bs
->firstseq
[0] == '-')
1058 fputs("-- ", stdout
);
1060 printbind(bs
->firstseq
, stdout
);
1063 printbind(bs
->lastseq
, stdout
);
1067 if (bs
->flags
& BS_LIST
)
1068 quotedzputs(bs
->bind
->nam
, stdout
);
1070 nicezputs(bs
->bind
->nam
, stdout
);
1072 printbind(bs
->str
, stdout
);
1076 /****************************/
1077 /* initialisation functions */
1078 /****************************/
1080 /* main initialisation entry point */
1086 createkeymapnamtab();
1088 keybuf
= (char *)zalloc(keybufsz
);
1089 lastnamed
= refthingy(t_undefinedkey
);
1092 /* cleanup entry point (for unloading the zle module) */
1096 cleanup_keymaps(void)
1098 unrefthingy(lastnamed
);
1099 deletehashtable(keymapnamtab
);
1100 zfree(keybuf
, keybufsz
);
1103 static char *cursorptr
;
1105 /* utility function for termcap output routine to add to string */
1108 add_cursor_char(int c
)
1114 /* interrogate termcap for cursor keys and add bindings to keymap */
1118 add_cursor_key(Keymap km
, int tccode
, Thingy thingy
, int defchar
)
1124 * Be careful not to try too hard with bindings for dubious or
1125 * dysfunctional terminals.
1127 if (tccan(tccode
) && !(termflags
& (TERM_NOUP
|TERM_BAD
|TERM_UNKNOWN
))) {
1129 * We can use the real termcap sequence. We need to
1130 * persuade termcap to output `move cursor 1 char' and capture it.
1133 tputs(tcstr
[tccode
], 1, add_cursor_char
);
1137 * Sanity checking. If the cursor key is zero-length (unlikely,
1138 * but this is termcap we're talking about), or it's a single
1139 * character, then we don't bind it.
1141 if (buf
[0] && buf
[1] && (buf
[0] != Meta
|| buf
[2]))
1145 /* Assume the normal VT100-like values. */
1146 sprintf(buf
, "\33[%c", defchar
);
1148 bindkey(km
, buf
, refthingy(thingy
), NULL
);
1151 * If the string looked like \e[? or \eO?, bind the other one, too.
1152 * This is necessary to make cursor keys work on many xterms with
1153 * both normal and application modes.
1155 if (buf
[0] == '\33' && (buf
[1] == '[' || buf
[1] == 'O') &&
1158 buf
[1] = (buf
[1] == '[') ? 'O' : '[';
1159 bindkey(km
, buf
, refthingy(thingy
), NULL
);
1163 /* Create the default keymaps. For efficiency reasons, this function *
1164 * assigns directly to the km->first array. It knows that there are no *
1165 * prefix bindings in the way, and that it is using a simple keymap. */
1169 default_bindings(void)
1171 Keymap vmap
= newkeymap(NULL
, "viins");
1172 Keymap emap
= newkeymap(NULL
, "emacs");
1173 Keymap amap
= newkeymap(NULL
, "vicmd");
1174 Keymap smap
= newkeymap(NULL
, ".safe");
1175 Keymap vimaps
[2], kptr
;
1179 /* vi insert mode and emacs mode: *
1180 * 0-31 taken from the tables *
1181 * 32-126 self-insert *
1182 * 127 same as entry[8] *
1183 * 128-255 self-insert */
1184 for (i
= 0; i
< 32; i
++) {
1185 vmap
->first
[i
] = refthingy(Th(viinsbind
[i
]));
1186 emap
->first
[i
] = refthingy(Th(emacsbind
[i
]));
1188 for (i
= 32; i
< 256; i
++) {
1189 vmap
->first
[i
] = refthingy(t_selfinsert
);
1190 emap
->first
[i
] = refthingy(t_selfinsert
);
1192 unrefthingy(t_selfinsert
);
1193 unrefthingy(t_selfinsert
);
1194 vmap
->first
[127] = refthingy(vmap
->first
[8]);
1195 emap
->first
[127] = refthingy(emap
->first
[8]);
1197 /* vi command mode: *
1198 * 0-127 taken from the table *
1199 * 128-255 undefined-key */
1200 for (i
= 0; i
< 128; i
++)
1201 amap
->first
[i
] = refthingy(Th(vicmdbind
[i
]));
1202 for (i
= 128; i
< 256; i
++)
1203 amap
->first
[i
] = refthingy(t_undefinedkey
);
1205 /* safe fallback keymap:
1206 * 0-255 self-insert, except: *
1207 * '\n' accept-line *
1208 * '\r' accept-line */
1209 for (i
= 0; i
< 256; i
++)
1210 smap
->first
[i
] = refthingy(t_selfinsert
);
1211 unrefthingy(t_selfinsert
);
1212 unrefthingy(t_selfinsert
);
1213 smap
->first
['\n'] = refthingy(t_acceptline
);
1214 smap
->first
['\r'] = refthingy(t_acceptline
);
1216 /* vt100 arrow keys are bound by default, for historical reasons. *
1217 * Both standard and keypad modes are supported. */
1221 for (i
= 0; i
< 2; i
++) {
1223 /* vi command and insert modes: arrow keys */
1224 add_cursor_key(kptr
, TCUPCURSOR
, t_uplineorhistory
, 'A');
1225 add_cursor_key(kptr
, TCDOWNCURSOR
, t_downlineorhistory
, 'B');
1226 add_cursor_key(kptr
, TCLEFTCURSOR
, t_vibackwardchar
, 'D');
1227 add_cursor_key(kptr
, TCRIGHTCURSOR
, t_viforwardchar
, 'C');
1230 /* emacs mode: arrow keys */
1231 add_cursor_key(emap
, TCUPCURSOR
, t_uplineorhistory
, 'A');
1232 add_cursor_key(emap
, TCDOWNCURSOR
, t_downlineorhistory
, 'B');
1233 add_cursor_key(emap
, TCLEFTCURSOR
, t_backwardchar
, 'D');
1234 add_cursor_key(emap
, TCRIGHTCURSOR
, t_forwardchar
, 'C');
1236 /* emacs mode: ^X sequences */
1237 bindkey(emap
, "\30*", refthingy(t_expandword
), NULL
);
1238 bindkey(emap
, "\30g", refthingy(t_listexpand
), NULL
);
1239 bindkey(emap
, "\30G", refthingy(t_listexpand
), NULL
);
1240 bindkey(emap
, "\30\16", refthingy(t_infernexthistory
), NULL
);
1241 bindkey(emap
, "\30\13", refthingy(t_killbuffer
), NULL
);
1242 bindkey(emap
, "\30\6", refthingy(t_vifindnextchar
), NULL
);
1243 bindkey(emap
, "\30\17", refthingy(t_overwritemode
), NULL
);
1244 bindkey(emap
, "\30\25", refthingy(t_undo
), NULL
);
1245 bindkey(emap
, "\30\26", refthingy(t_vicmdmode
), NULL
);
1246 bindkey(emap
, "\30\12", refthingy(t_vijoin
), NULL
);
1247 bindkey(emap
, "\30\2", refthingy(t_vimatchbracket
), NULL
);
1248 bindkey(emap
, "\30s", refthingy(t_historyincrementalsearchforward
), NULL
);
1249 bindkey(emap
, "\30r", refthingy(t_historyincrementalsearchbackward
), NULL
);
1250 bindkey(emap
, "\30u", refthingy(t_undo
), NULL
);
1251 bindkey(emap
, "\30\30", refthingy(t_exchangepointandmark
), NULL
);
1252 bindkey(emap
, "\30=", refthingy(t_whatcursorposition
), NULL
);
1254 /* emacs mode: ESC sequences, all taken from the meta binding table */
1257 for (i
= 0; i
< 128; i
++)
1258 if (metabind
[i
] != z_undefinedkey
) {
1260 bindkey(emap
, buf
, refthingy(Th(metabind
[i
])), NULL
);
1263 /* Put the keymaps in the right namespace. The "main" keymap *
1264 * will be linked to the "emacs" keymap, except that if VISUAL *
1265 * or EDITOR contain the string "vi" then it will be linked to *
1266 * the "viins" keymap. */
1267 linkkeymap(vmap
, "viins", 0);
1268 linkkeymap(emap
, "emacs", 0);
1269 linkkeymap(amap
, "vicmd", 0);
1270 linkkeymap(smap
, ".safe", 1);
1271 if (((ed
= zgetenv("VISUAL")) && strstr(ed
, "vi")) ||
1272 ((ed
= zgetenv("EDITOR")) && strstr(ed
, "vi")))
1273 linkkeymap(vmap
, "main", 0);
1275 linkkeymap(emap
, "main", 0);
1277 /* the .safe map cannot be modified or deleted */
1278 smap
->flags
|= KM_IMMUTABLE
;
1280 /* isearch keymap: initially empty */
1281 isearch_keymap
= newkeymap(NULL
, "isearch");
1282 linkkeymap(isearch_keymap
, "isearch", 0);
1284 /* command keymap: make sure accept-line and send-break are bound */
1285 command_keymap
= newkeymap(NULL
, "command");
1286 command_keymap
->first
['\n'] = refthingy(t_acceptline
);
1287 command_keymap
->first
['\r'] = refthingy(t_acceptline
);
1288 command_keymap
->first
['G'&0x1F] = refthingy(t_sendbreak
);
1289 linkkeymap(command_keymap
, "command", 0);
1292 /*************************/
1293 /* reading key sequences */
1294 /*************************/
1296 /* read a sequence of keys that is bound to some command in a keymap */
1300 getkeymapcmd(Keymap km
, Thingy
*funcp
, char **strp
)
1302 Thingy func
= t_undefinedkey
;
1304 int lastlen
= 0, lastc
= lastchar
;
1309 * getkeybuf returns multibyte strings, which may not
1310 * yet correspond to complete wide characters, regardless
1311 * of the locale. This is because we can't be sure whether
1312 * the key bindings and keyboard input always return such
1313 * characters. So we always look up bindings for each
1314 * chunk of string. Intelligence within self-insert tries
1315 * to fix up insertion of real wide characters properly.
1317 * Note that this does not stop the user binding wide characters to
1318 * arbitrary functions, just so long as the string used in the
1319 * argument to bindkey is in the correct form for the locale.
1320 * That's beyond our control.
1322 while(getkeybuf(!!lastlen
) != EOF
) {
1325 int loc
= !!localkeymap
;
1329 loc
= ((f
= keybind(localkeymap
, keybuf
, &s
)) != t_undefinedkey
);
1330 ispfx
= keyisprefix(localkeymap
, keybuf
);
1333 f
= keybind(km
, keybuf
, &s
);
1334 ispfx
|= keyisprefix(km
, keybuf
);
1336 if (f
!= t_undefinedkey
) {
1337 lastlen
= keybuflen
;
1345 if(!lastlen
&& keybuflen
)
1346 lastlen
= keybuflen
;
1349 if(lastlen
!= keybuflen
) {
1350 unmetafy(keybuf
+ lastlen
, &keybuflen
);
1351 ungetbytes(keybuf
+lastlen
, keybuflen
);
1353 vichgbufptr
-= keybuflen
;
1354 keybuf
[lastlen
] = 0;
1362 * Add a (possibly metafied) byte to the key input so far.
1363 * This handles individual bytes of a multibyte string separately;
1364 * see note in getkeymapcmd. Hence there is no wide character
1365 * support at this level.
1367 * TODO: Need to be careful about whether we return EOF in the
1368 * middle of a wide character. However, I think we're OK since
1369 * EOF and 0xff are distinct and we're reading bytes from the
1370 * lower level, so EOF really does mean something went wrong. Even so,
1371 * I'm worried enough to leave this note here for now.
1378 int c
= getbyte((long)w
, NULL
);
1382 if(keybuflen
+ 3 > keybufsz
)
1383 keybuf
= realloc(keybuf
, keybufsz
*= 2);
1385 keybuf
[keybuflen
++] = Meta
;
1386 keybuf
[keybuflen
++] = c
^ 32;
1388 keybuf
[keybuflen
++] = c
;
1389 keybuf
[keybuflen
] = 0;
1393 /* Push back the last command sequence read by getkeymapcmd(). *
1394 * Must be executed at most once after each getkeymapcmd(). */
1400 ungetbytes(keybuf
, keybuflen
);
1403 /* read a command from the current keymap, with widgets */
1414 seq
= getkeymapcmd(curkeymap
, &func
, &str
);
1422 zerr("string inserting another one too many times");
1426 pb
= unmetafy(ztrdup(str
), &len
);
1427 ungetbytes(pb
, len
);
1428 zfree(pb
, strlen(str
) + 1);
1431 if (func
== Th(z_executenamedcmd
) && !statusline
) {
1432 while(func
== Th(z_executenamedcmd
))
1433 func
= executenamedcommand("execute: ");
1435 func
= t_undefinedkey
;
1436 else if(func
!= Th(z_executelastnamedcmd
)) {
1437 unrefthingy(lastnamed
);
1438 lastnamed
= refthingy(func
);
1441 if (func
== Th(z_executelastnamedcmd
))
1448 zlesetkeymap(int mode
)
1450 Keymap km
= openkeymap((mode
== VIMODE
) ? "viins" : "emacs");
1453 linkkeymap(km
, "main", 0);
1458 readcommand(UNUSED(char **args
))
1460 Thingy thingy
= getkeycmd();
1465 setsparam("REPLY", ztrdup(thingy
->nam
));