mirror of
git://git.code.sf.net/p/zsh/code
synced 2025-01-01 05:16:05 +01:00
19733 with docs tweaked: keymaps for vared and zed
This commit is contained in:
parent
294ce1cd6a
commit
4688564c0a
6 changed files with 147 additions and 86 deletions
|
@ -1,3 +1,10 @@
|
|||
2004-04-06 Peter Stephenson <pws@csr.com>
|
||||
|
||||
* 19733 (with improved documentation): Doc/Zsh/contrib.yo,
|
||||
Doc/Zsh/zle.yo, Functions/Misc/zed, Src/Zle/zle_keymap.c,
|
||||
Src/Zle/zle_main.c: vared -M and -m allow you to provide
|
||||
main and alternate keymap; zed will use keymaps zed and zed-vicmd.
|
||||
|
||||
2004-04-05 Peter Stephenson <pws@csr.com>
|
||||
|
||||
* 19728: Doc/Zsh/expn.yo: explain that (^F) (from 19717)
|
||||
|
|
|
@ -1312,12 +1312,7 @@ See the comments in the function for a few extra tips.
|
|||
)
|
||||
findex(zed)
|
||||
item(tt(zed) [ tt(-f) ] var(name))(
|
||||
This function uses the ZLE editor to edit a file or function. It rebinds
|
||||
the return key to insert a line break, and adds bindings for `tt(^X^W)' in
|
||||
the tt(emacs) keymap and `tt(ZZ)' in the tt(vicmd) keymap to accept (and
|
||||
therefore write, in the case of a file) the edited file or function.
|
||||
Keybindings are otherwise the standard ones; completion is available, and
|
||||
styles may be set with the context prefix `tt(:completion:zed)'.
|
||||
This function uses the ZLE editor to edit a file or function.
|
||||
|
||||
Only one var(name) argument is recognized (additional arguments are
|
||||
ignored). If the tt(-f) option is given, the name is taken to be that of
|
||||
|
@ -1328,6 +1323,26 @@ autoload file.
|
|||
|
||||
Without tt(-f), var(name) is the path name of the file to edit, which need
|
||||
not exist; it is created on write, if necessary.
|
||||
|
||||
While editing, the function sets the main keymap to tt(zed) and the
|
||||
vi command keymap to tt(zed-vicmd). These will be copied from the existing
|
||||
tt(main) and tt(vicmd) keymaps if they do not exist the first time tt(zed)
|
||||
is run. They can be used to provide special key bindings used only in zed.
|
||||
|
||||
If it creates the keymap, tt(zed) rebinds the return key to insert a line
|
||||
break and `tt(^X^W)' to accept the edit in the tt(zed) keymap, and binds
|
||||
`tt(ZZ)' to accept the edit in the tt(zed-vicmd) keymap. If the tt(zed)
|
||||
keymap is created by hand, the user will need to bind:
|
||||
|
||||
example(zle -M zed '^M' self-insert-unmeta
|
||||
zle -M zed '^X^W' accept-line)
|
||||
|
||||
for this behaviour, and if tt(zed-vicmd) is created by hand,
|
||||
|
||||
example(zle -M zed-vicmd 'ZZ' accept-line)
|
||||
|
||||
Completion is available, and styles may be set with the context prefix
|
||||
`tt(:completion:zed)'.
|
||||
)
|
||||
findex(zcp)
|
||||
findex(zln)
|
||||
|
|
|
@ -265,7 +265,8 @@ by `tt(bindkey -m)'.
|
|||
findex(vared)
|
||||
cindex(parameters, editing)
|
||||
cindex(editing parameters)
|
||||
item(tt(vared) [ tt(-Aache) ] [ tt(-p) var(prompt) ] [ tt(-r) var(rprompt) ] var(name))(
|
||||
xitem(tt(vared) [ tt(-Aache) ] [ tt(-p) var(prompt) ] [ tt(-r) var(rprompt) ])
|
||||
item( [ -M var(main-keymap) ] [ -m var(vicmd-keymap) ] var(name))(
|
||||
The value of the parameter var(name) is loaded into the edit
|
||||
buffer, and the line editor is invoked. When the editor exits,
|
||||
var(name) is set to the string value returned by the editor.
|
||||
|
@ -289,9 +290,16 @@ created automatically, even without tt(-c).
|
|||
If the tt(-p) flag is given, the following string will be taken as
|
||||
the prompt to display at the left. If the tt(-r) flag is given,
|
||||
the following string gives the prompt to display at the right. If the
|
||||
tt(-h) flag is specified, the history can be accessed from ZLE. If the
|
||||
tt(-h) flag is specified, the history can be accessed from ZLE. If the
|
||||
tt(-e) flag is given, typing tt(^D) (Control-D) on an empty line
|
||||
causes tt(vared) to exit immediately with a non-zero return value.
|
||||
|
||||
The tt(-M) option gives a keymap to link to the tt(main) keymap during
|
||||
editing, and the tt(-m) option gives a keymap to link to the tt(vicmd)
|
||||
keymap during editing. For vi-style editing, this allows a pair of keymaps
|
||||
to override tt(viins) and tt(vicmd). For emacs-style editing, only tt(-M)
|
||||
is normally needed but the tt(-m) option may still be used. On exit, the
|
||||
previous keymaps will be restored.
|
||||
)
|
||||
findex(zle)
|
||||
cindex(widgets, rebinding)
|
||||
|
|
|
@ -10,7 +10,7 @@
|
|||
# compctl -f -x 'w[1,-f]' -F -- zed
|
||||
#
|
||||
|
||||
local var fun cleanup
|
||||
local var fun
|
||||
# We do not want timeout while we are editing a file
|
||||
integer TMOUT=0
|
||||
|
||||
|
@ -24,20 +24,27 @@ local curcontext=zed:::
|
|||
zstyle -m ":completion:zed:*" insert-tab '*' ||
|
||||
zstyle ":completion:zed:*" insert-tab yes
|
||||
|
||||
# catch interrupts
|
||||
cleanup="$(bindkey -L "^M"; bindkey -L -M emacs "^X^W"; bindkey -aL "ZZ"
|
||||
echo "trap - INT EXIT"; trap)"
|
||||
trap "return 130" INT
|
||||
trap "$cleanup" EXIT
|
||||
if ! bindkey -M zed >&/dev/null; then
|
||||
# Make the zed keymap a copy of the current main.
|
||||
bindkey -N zed main
|
||||
|
||||
# Assign some default keys.
|
||||
# Depending on your stty's, you may be able to use ^J as accept-line, else:
|
||||
|
||||
# The following isn't useful if we are copying viins, but that's
|
||||
# a nicety.
|
||||
bindkey -M zed '^x^w' accept-line
|
||||
bindkey -M zed '^M' self-insert-unmeta
|
||||
fi
|
||||
if ! bindkey -M zed-vicmd >&/dev/null; then
|
||||
bindkey -N zed-vicmd vicmd
|
||||
|
||||
bindkey -M zed-vicmd "ZZ" accept-line
|
||||
fi
|
||||
|
||||
# don't mangle !'s
|
||||
setopt localoptions nobanghist
|
||||
|
||||
bindkey "^M" self-insert-unmeta
|
||||
# Depending on your stty's, you may be able to use ^J as accept-line, else:
|
||||
bindkey -M emacs "^X^W" accept-line
|
||||
bindkey -a "ZZ" accept-line
|
||||
|
||||
if ((fun)) then
|
||||
var="$(functions $1)"
|
||||
# If function is undefined but autoloadable, load it
|
||||
|
@ -55,10 +62,10 @@ $(<$dir/$1)
|
|||
var="$1() {
|
||||
}"
|
||||
fi
|
||||
vared var && eval "$cleanup ;" function "$var"
|
||||
vared -M zed -m zed-vicmd var && eval function "$var"
|
||||
else
|
||||
[[ -f $1 ]] && var="$(<$1)"
|
||||
while vared var
|
||||
while vared -M zed -m zed-vicmd var
|
||||
do
|
||||
(print -r -- "$var" >| $1) && break
|
||||
echo -n -e '\a'
|
||||
|
|
|
@ -169,8 +169,7 @@ freekeymapnamnode(HashNode hn)
|
|||
KeymapName kmn = (KeymapName) hn;
|
||||
|
||||
zsfree(kmn->nam);
|
||||
if(!--kmn->keymap->rc)
|
||||
deletekeymap(kmn->keymap);
|
||||
unrefkeymap(kmn->keymap);
|
||||
zfree(kmn, sizeof(*kmn));
|
||||
}
|
||||
|
||||
|
@ -355,8 +354,7 @@ linkkeymap(Keymap km, char *name, int imm)
|
|||
return 1;
|
||||
if(n->keymap == km)
|
||||
return 0;
|
||||
if(!--n->keymap->rc)
|
||||
deletekeymap(n->keymap);
|
||||
unrefkeymap(n->keymap);
|
||||
n->keymap = km;
|
||||
} else {
|
||||
n = makekeymapnamnode(km);
|
||||
|
@ -364,10 +362,23 @@ linkkeymap(Keymap km, char *name, int imm)
|
|||
n->flags |= KMN_IMMORTAL;
|
||||
keymapnamtab->addnode(keymapnamtab, ztrdup(name), n);
|
||||
}
|
||||
km->rc++;
|
||||
refkeymap(km);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**/
|
||||
void refkeymap(Keymap km)
|
||||
{
|
||||
km->rc++;
|
||||
}
|
||||
|
||||
/**/
|
||||
void unrefkeymap(Keymap km)
|
||||
{
|
||||
if (!--km->rc)
|
||||
deletekeymap(km);
|
||||
}
|
||||
|
||||
/* Select a keymap as the current ZLE keymap. Can optionally fall back *
|
||||
* on the guaranteed safe keymap if it fails. */
|
||||
|
||||
|
|
|
@ -987,6 +987,45 @@ handleprefixes(void)
|
|||
initmodifier(&zmod);
|
||||
}
|
||||
|
||||
/**/
|
||||
static int
|
||||
savekeymap(char *cmdname, char *oldname, char *newname, Keymap *savemapptr)
|
||||
{
|
||||
Keymap km = openkeymap(newname);
|
||||
|
||||
if (km) {
|
||||
*savemapptr = openkeymap(oldname);
|
||||
/* I love special cases */
|
||||
if (*savemapptr == km)
|
||||
*savemapptr = NULL;
|
||||
else {
|
||||
/* make sure this doesn't get deleted. */
|
||||
if (*savemapptr)
|
||||
refkeymap(*savemapptr);
|
||||
linkkeymap(km, oldname, 0);
|
||||
}
|
||||
return 0;
|
||||
} else {
|
||||
zwarnnam(cmdname, "no such keymap: %s", newname, 0);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
/**/
|
||||
static void
|
||||
restorekeymap(char *cmdname, char *oldname, char *newname, Keymap savemap)
|
||||
{
|
||||
if (savemap) {
|
||||
linkkeymap(savemap, oldname, 0);
|
||||
/* we incremented the reference count above */
|
||||
unrefkeymap(savemap);
|
||||
} else if (newname) {
|
||||
/* urr... can this happen? */
|
||||
zwarnnam(cmdname,
|
||||
"keymap %s was not defined, not restored", oldname, 0);
|
||||
}
|
||||
}
|
||||
|
||||
/* this exports the argument we are currently vared'iting if != NULL */
|
||||
|
||||
/**/
|
||||
|
@ -1002,9 +1041,10 @@ bin_vared(char *name, char **args, Options ops, int func)
|
|||
struct value vbuf;
|
||||
Value v;
|
||||
Param pm = 0;
|
||||
int create = 0, ifl;
|
||||
int ifl;
|
||||
int type = PM_SCALAR, obreaks = breaks, haso = 0;
|
||||
char *p1 = NULL, *p2 = NULL;
|
||||
char *p1, *p2, *main_keymapname, *vicmd_keymapname;
|
||||
Keymap main_keymapsave = NULL, vicmd_keymapsave = NULL;
|
||||
FILE *oshout = NULL;
|
||||
|
||||
if ((interact && unset(USEZLE)) || !strcmp(term, "emacs")) {
|
||||
|
@ -1016,61 +1056,23 @@ bin_vared(char *name, char **args, Options ops, int func)
|
|||
return 1;
|
||||
}
|
||||
|
||||
/* all options are handled as arguments */
|
||||
while (*args && **args == '-') {
|
||||
while (*++(*args))
|
||||
switch (**args) {
|
||||
case 'c':
|
||||
/* -c option -- allow creation of the parameter if it doesn't
|
||||
yet exist */
|
||||
create = 1;
|
||||
break;
|
||||
case 'a':
|
||||
type = PM_ARRAY;
|
||||
break;
|
||||
case 'A':
|
||||
type = PM_HASHED;
|
||||
break;
|
||||
case 'p':
|
||||
/* -p option -- set main prompt string */
|
||||
if ((*args)[1])
|
||||
p1 = *args + 1, *args = "" - 1;
|
||||
else if (args[1])
|
||||
p1 = *(++args), *args = "" - 1;
|
||||
else {
|
||||
zwarnnam(name, "prompt string expected after -%c", NULL,
|
||||
**args);
|
||||
return 1;
|
||||
}
|
||||
break;
|
||||
case 'r':
|
||||
/* -r option -- set right prompt string */
|
||||
if ((*args)[1])
|
||||
p2 = *args + 1, *args = "" - 1;
|
||||
else if (args[1])
|
||||
p2 = *(++args), *args = "" - 1;
|
||||
else {
|
||||
zwarnnam(name, "prompt string expected after -%c", NULL,
|
||||
**args);
|
||||
return 1;
|
||||
}
|
||||
break;
|
||||
case 'h':
|
||||
/* -h option -- enable history */
|
||||
ops->ind['h'] = 1;
|
||||
break;
|
||||
case 'e':
|
||||
/* -e option -- enable EOF */
|
||||
ops->ind['e'] = 1;
|
||||
break;
|
||||
default:
|
||||
/* unrecognised option character */
|
||||
zwarnnam(name, "unknown option: %s", *args, 0);
|
||||
return 1;
|
||||
}
|
||||
args++;
|
||||
if (OPT_ISSET(ops,'A'))
|
||||
{
|
||||
if (OPT_ISSET(ops, 'a'))
|
||||
{
|
||||
zwarnnam(name, "specify only one of -a and -A", NULL, 0);
|
||||
return 1;
|
||||
}
|
||||
type = PM_HASHED;
|
||||
}
|
||||
if (type && !create) {
|
||||
else if (OPT_ISSET(ops,'a'))
|
||||
type = PM_ARRAY;
|
||||
p1 = OPT_ARG_SAFE(ops,'p');
|
||||
p2 = OPT_ARG_SAFE(ops,'r');
|
||||
main_keymapname = OPT_ARG_SAFE(ops,'M');
|
||||
vicmd_keymapname = OPT_ARG_SAFE(ops,'m');
|
||||
|
||||
if (type != PM_SCALAR && !OPT_ISSET(ops,'c')) {
|
||||
zwarnnam(name, "-%s ignored", type == PM_ARRAY ? "a" : "A", 0);
|
||||
}
|
||||
|
||||
|
@ -1082,9 +1084,9 @@ bin_vared(char *name, char **args, Options ops, int func)
|
|||
/* handle non-existent parameter */
|
||||
s = args[0];
|
||||
queue_signals();
|
||||
v = fetchvalue(&vbuf, &s, (!create || type == PM_SCALAR),
|
||||
v = fetchvalue(&vbuf, &s, (!OPT_ISSET(ops,'c') || type == PM_SCALAR),
|
||||
SCANPM_WANTKEYS|SCANPM_WANTVALS|SCANPM_MATCHMANY);
|
||||
if (!v && !create) {
|
||||
if (!v && !OPT_ISSET(ops,'c')) {
|
||||
unqueue_signals();
|
||||
zwarnnam(name, "no such variable: %s", args[0], 0);
|
||||
return 1;
|
||||
|
@ -1156,6 +1158,13 @@ bin_vared(char *name, char **args, Options ops, int func)
|
|||
/* edit the parameter value */
|
||||
zpushnode(bufstack, s);
|
||||
|
||||
if (main_keymapname &&
|
||||
savekeymap(name, "main", main_keymapname, &main_keymapsave))
|
||||
main_keymapname = NULL;
|
||||
if (vicmd_keymapname &&
|
||||
savekeymap(name, "vicmd", vicmd_keymapname, &vicmd_keymapsave))
|
||||
vicmd_keymapname = NULL;
|
||||
|
||||
varedarg = *args;
|
||||
ifl = isfirstln;
|
||||
if (OPT_ISSET(ops,'h'))
|
||||
|
@ -1167,6 +1176,10 @@ bin_vared(char *name, char **args, Options ops, int func)
|
|||
hend(NULL);
|
||||
isfirstln = ifl;
|
||||
varedarg = ova;
|
||||
|
||||
restorekeymap(name, "main", main_keymapname, main_keymapsave);
|
||||
restorekeymap(name, "vicmd", vicmd_keymapname, vicmd_keymapsave);
|
||||
|
||||
if (haso) {
|
||||
fclose(shout); /* close(SHTTY) */
|
||||
shout = oshout;
|
||||
|
@ -1182,7 +1195,7 @@ bin_vared(char *name, char **args, Options ops, int func)
|
|||
if (t[strlen(t) - 1] == '\n')
|
||||
t[strlen(t) - 1] = '\0';
|
||||
/* final assignment of parameter value */
|
||||
if (create) {
|
||||
if (OPT_ISSET(ops,'c')) {
|
||||
unsetparam(args[0]);
|
||||
createparam(args[0], type);
|
||||
}
|
||||
|
@ -1353,7 +1366,7 @@ zleaftertrap(Hookdef dummy, void *dat)
|
|||
|
||||
static struct builtin bintab[] = {
|
||||
BUILTIN("bindkey", 0, bin_bindkey, 0, -1, 0, "evaM:ldDANmrsLRp", NULL),
|
||||
BUILTIN("vared", 0, bin_vared, 1, 7, 0, NULL, NULL),
|
||||
BUILTIN("vared", 0, bin_vared, 1, 7, 0, "aAchM:m:p:r:", NULL),
|
||||
BUILTIN("zle", 0, bin_zle, 0, -1, 0, "aAcCDFgGIKlLmMNRU", NULL),
|
||||
};
|
||||
|
||||
|
|
Loading…
Reference in a new issue