28227: improved documentation on keymaps

28226: improve bindkey -lL for aliased keymaps
This commit is contained in:
Peter Stephenson 2010-09-05 19:24:44 +00:00
parent aa24f1a703
commit 17dee17e4e
3 changed files with 133 additions and 23 deletions

View file

@ -1,3 +1,11 @@
2010-09-05 Peter Stephenson <p.w.stephenson@ntlworld.com>
* 28226: Doc/Zsh/zle.yo, Src/Zle/zle_keymap.c: "bindkey -lL" now
lists aliased keymaps in a more useful way.
* 28227: Doc/Zsh/zle.yo: a few remarks on the question of
keymaps.
2010-09-02 Peter Stephenson <pws@csr.com> 2010-09-02 Peter Stephenson <pws@csr.com>
* users/15350: Doc/expn.yo: explain the strange rounding rules for * users/15350: Doc/expn.yo: explain the strange rounding rules for
@ -13591,5 +13599,5 @@
***************************************************** *****************************************************
* This is used by the shell to define $ZSH_PATCHLEVEL * This is used by the shell to define $ZSH_PATCHLEVEL
* $Revision: 1.5068 $ * $Revision: 1.5069 $
***************************************************** *****************************************************

View file

@ -149,21 +149,27 @@ xitem(tt(bindkey) [ var(options) ] tt(-r) var(in-string) ...)
xitem(tt(bindkey) [ var(options) ] tt(-s) var(in-string out-string) ...) xitem(tt(bindkey) [ var(options) ] tt(-s) var(in-string out-string) ...)
xitem(tt(bindkey) [ var(options) ] var(in-string command) ...) xitem(tt(bindkey) [ var(options) ] var(in-string command) ...)
item(tt(bindkey) [ var(options) ] [ var(in-string) ])( item(tt(bindkey) [ var(options) ] [ var(in-string) ])(
tt(bindkey)'s options can be divided into three categories: keymap selection, tt(bindkey)'s options can be divided into three categories: keymap
operation selection, and others. The keymap selection options are: selection for the current command, operation selection, and others. The
keymap selection options are:
startitem() startitem()
item(tt(-e))( item(tt(-e))(
Selects keymap `tt(emacs)', and also links it to `tt(main)'. Selects keymap `tt(emacs)' for any operations by the current command,
and also links `tt(emacs)' to `tt(main)' so that it is selected by
default the next time the editor starts.
) )
item(tt(-v))( item(tt(-v))(
Selects keymap `tt(viins)', and also links it to `tt(main)'. Selects keymap `tt(viins)' for any operations by the current command,
and also links `tt(viins)' to `tt(main)' so that it is selected by default
the next time the editor starts.
) )
item(tt(-a))( item(tt(-a))(
Selects keymap `tt(vicmd)'. Selects keymap `tt(vicmd)' for any operations by the current command.
) )
item(tt(-M) var(keymap))( item(tt(-M) var(keymap))(
The var(keymap) specifies a keymap name. The var(keymap) specifies a keymap name that is selected for any
operations by the current command.
) )
enditem() enditem()
@ -175,7 +181,8 @@ startitem()
item(tt(-l))( item(tt(-l))(
List all existing keymap names. If the tt(-L) List all existing keymap names. If the tt(-L)
option is also used, list in the form of tt(bindkey) option is also used, list in the form of tt(bindkey)
commands to create the keymaps. commands to create the keymaps; this combination also shows
which keymap is linked to `tt(main)', if any.
) )
item(tt(-d))( item(tt(-d))(
Delete all existing keymaps and reset to the default state. Delete all existing keymaps and reset to the default state.
@ -1207,11 +1214,10 @@ mini-buffer.
) )
enditem() enditem()
Any multi-character string that is not bound to one of the above functions Any character that is not bound to one of the above functions, or
will beep and interrupt the search, leaving the last found line in the tt(self-insert) or tt(self-insert-unmeta), will cause the mode to be
buffer. Any single character that is not bound to one of the above exited. The character is then looked up and executed in the keymap in
functions, or tt(self-insert) or tt(self-insert-unmeta), will have the same effect at that point.
effect but the function will be executed.
When called from a widget function by the tt(zle) command, the incremental When called from a widget function by the tt(zle) command, the incremental
search commands can take a string argument. This will be treated as a search commands can take a string argument. This will be treated as a

View file

@ -58,11 +58,24 @@ struct keymapname {
Keymap keymap; /* the keymap itsef */ Keymap keymap; /* the keymap itsef */
}; };
/* Can't be deleted (.safe) */
#define KMN_IMMORTAL (1<<1) #define KMN_IMMORTAL (1<<1)
struct keymap { struct keymap {
Thingy first[256]; /* base binding of each character */ Thingy first[256]; /* base binding of each character */
HashTable multi; /* multi-character bindings */ HashTable multi; /* multi-character bindings */
/*
* The "real" name of this keymap.
* For an aliased keymap, this is the first name to be defined.
* If this is deleted but there are other names we randomly pick another
* one, avoiding the name "main". The principal use
* for this is to make it clear what "main" is aliased to.
*
* If "main" is the only name for this map, this will be NULL.
* That's fine, there's no alias. We'll pick a primary if we
* alias "main" again.
*/
KeymapName primary;
int flags; /* various flags (see below) */ int flags; /* various flags (see below) */
int rc; /* reference count */ int rc; /* reference count */
}; };
@ -162,6 +175,70 @@ makekeymapnamnode(Keymap keymap)
return kmn; return kmn;
} }
/*
* Reference a keymap from a keymapname.
* Used when linking keymaps. This includes the first link to a
* newly created keymap.
*/
static void
refkeymap_by_name(KeymapName kmn)
{
refkeymap(kmn->keymap);
if (!kmn->keymap->primary && strcmp(kmn->nam, "main") != 0)
kmn->keymap->primary = kmn;
}
/*
* Communication to keymap scanner when looking for a new primary name.
*/
static Keymap km_rename_me;
/* Find a new primary name for a keymap. See below. */
static void
scanprimaryname(HashNode hn, int ignored)
{
KeymapName n = (KeymapName) hn;
(void)ignored;
/* Check if we've already found a new primary name. */
if (km_rename_me->primary)
return;
/* Don't use "main". */
if (!strcmp(n->nam, "main"))
return;
if (n->keymap == km_rename_me)
km_rename_me->primary = n;
}
/*
* Unreference a keymap from a keymapname.
* Used when unlinking keymaps to ensure there is still a primary
* name for the keymap, unless it is an unaliased "main".
*/
static void
unrefkeymap_by_name(KeymapName kmname)
{
Keymap km = kmname->keymap;
if (unrefkeymap(km) && km->primary == kmname) {
/*
* The primary name for the keymap has gone,
* but the keymap is still referred to; find a new primary name
* for it. Sort the keymap to make the result deterministic.
*/
/* Set the primary name to NULL so we can check if we've found one */
km->primary = NULL;
km_rename_me = km;
scanhashtable(keymapnamtab, 1, 0, 0, scanprimaryname, 0);
/* Just for neatness */
km_rename_me = NULL;
}
}
/**/ /**/
static void static void
freekeymapnamnode(HashNode hn) freekeymapnamnode(HashNode hn)
@ -169,7 +246,7 @@ freekeymapnamnode(HashNode hn)
KeymapName kmn = (KeymapName) hn; KeymapName kmn = (KeymapName) hn;
zsfree(kmn->nam); zsfree(kmn->nam);
unrefkeymap(kmn->keymap); unrefkeymap_by_name(kmn);
zfree(kmn, sizeof(*kmn)); zfree(kmn, sizeof(*kmn));
} }
@ -354,7 +431,7 @@ linkkeymap(Keymap km, char *name, int imm)
return 1; return 1;
if(n->keymap == km) if(n->keymap == km)
return 0; return 0;
unrefkeymap(n->keymap); unrefkeymap_by_name(n);
n->keymap = km; n->keymap = km;
} else { } else {
n = makekeymapnamnode(km); n = makekeymapnamnode(km);
@ -362,21 +439,29 @@ linkkeymap(Keymap km, char *name, int imm)
n->flags |= KMN_IMMORTAL; n->flags |= KMN_IMMORTAL;
keymapnamtab->addnode(keymapnamtab, ztrdup(name), n); keymapnamtab->addnode(keymapnamtab, ztrdup(name), n);
} }
refkeymap(km); refkeymap_by_name(n);
return 0; return 0;
} }
/**/ /**/
void refkeymap(Keymap km) void
refkeymap(Keymap km)
{ {
km->rc++; km->rc++;
} }
/* Unreference keymap, returning new reference count, 0 if deleted */
/**/ /**/
void unrefkeymap(Keymap km) int
unrefkeymap(Keymap km)
{ {
if (!--km->rc) if (!--km->rc) {
deletekeymap(km); deletekeymap(km);
return 0;
}
return km->rc;
} }
/* Select a keymap as the current ZLE keymap. Can optionally fall back * /* Select a keymap as the current ZLE keymap. Can optionally fall back *
@ -734,10 +819,21 @@ scanlistmaps(HashNode hn, int list)
{ {
KeymapName n = (KeymapName) hn; KeymapName n = (KeymapName) hn;
if(list) { if (list) {
fputs("bindkey -N ", stdout); Keymap km = n->keymap;
if(n->nam[0] == '-') fputs("bindkey -", stdout);
fputs("-- ", stdout); if (km->primary && km->primary != n) {
KeymapName pn = km->primary;
fputs("A ", stdout);
if (pn->nam[0] == '-')
fputs("-- ", stdout);
quotedzputs(pn->nam, stdout);
fputc(' ', stdout);
} else {
fputs("N ", stdout);
if(n->nam[0] == '-')
fputs("-- ", stdout);
}
quotedzputs(n->nam, stdout); quotedzputs(n->nam, stdout);
} else } else
nicezputs(n->nam, stdout); nicezputs(n->nam, stdout);