1
0
Fork 0
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:
Peter Stephenson 2004-04-06 09:16:57 +00:00
parent 294ce1cd6a
commit 4688564c0a
6 changed files with 147 additions and 86 deletions

View file

@ -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)

View file

@ -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)

View file

@ -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)

View file

@ -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'

View file

@ -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. */

View file

@ -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),
};