From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 6490 invoked from network); 5 Apr 2004 17:51:12 -0000 Received: from sunsite.dk (130.225.247.90) by ns1.primenet.com.au with SMTP; 5 Apr 2004 17:51:12 -0000 Received: (qmail 9905 invoked by alias); 5 Apr 2004 17:51:03 -0000 Mailing-List: contact zsh-workers-help@sunsite.dk; run by ezmlm Precedence: bulk X-No-Archive: yes X-Seq: 19733 Received: (qmail 9890 invoked from network); 5 Apr 2004 17:51:02 -0000 Received: from localhost (HELO sunsite.dk) (127.0.0.1) by localhost with SMTP; 5 Apr 2004 17:51:02 -0000 X-MessageWall-Score: 0 (sunsite.dk) Received: from [130.225.247.86] by sunsite.dk (MessageWall 1.0.8) with SMTP; 5 Apr 2004 17:51:2 -0000 Received: (qmail 4733 invoked from network); 5 Apr 2004 17:51:02 -0000 Received: from lhuumrelay3.lnd.ops.eu.uu.net (62.189.58.19) by a.mx.sunsite.dk with SMTP; 5 Apr 2004 17:51:00 -0000 Received: from MAILSWEEPER01.csr.com (mailhost1.csr.com [62.189.183.235]) by lhuumrelay3.lnd.ops.eu.uu.net (8.11.0/8.11.0) with ESMTP id i35HoXv25272 for ; Mon, 5 Apr 2004 17:50:33 GMT Received: from EXCHANGE02.csr.com (unverified [192.168.137.45]) by MAILSWEEPER01.csr.com (Content Technologies SMTPRS 4.3.12) with ESMTP id for ; Mon, 5 Apr 2004 18:50:08 +0100 Received: from csr.com ([192.168.144.127]) by EXCHANGE02.csr.com with Microsoft SMTPSVC(5.0.2195.6713); Mon, 5 Apr 2004 18:53:39 +0100 To: zsh-workers@sunsite.dk Subject: PATCH: Re: .zshrc sanity check In-reply-to: "Jean Chalard"'s message of "Mon, 05 Apr 2004 17:48:16 +0200." <20040405154816.GA19743@epita.fr> Date: Mon, 05 Apr 2004 18:50:32 +0100 Message-ID: <466.1081187432@csr.com> From: Peter Stephenson X-OriginalArrivalTime: 05 Apr 2004 17:53:39.0452 (UTC) FILETIME=[ED2C8BC0:01C41B36] X-Spam-Checker-Version: SpamAssassin 2.63 on a.mx.sunsite.dk X-Spam-Level: X-Spam-Status: No, hits=0.2 required=6.0 tests=EXCUSE_16 autolearn=no version=2.63 X-Spam-Hits: 0.2 Jean Chalard wrote: > You bind history-beginning-search-backward on the up key. While I find > this really useful (and I don't even imagine using my shell without > this kind of binding, though I use history-search-backward), this has > the drawback that the up arrow doesn't work as expected any more in > zed sessions. It seems to me that many people like this binding, too. A more general solution to this is to allow zed to use its own keymaps. Then you can bind anything you like: bindkey -N zed main bindkey -M zed "\e[A" up-line-or-history bindkey -M zed "\e[B" down-line-or-history I added this to vared, since otherwise ensuring that the keymaps are restored under all circumstances is rather hairy; plus it's generally quite useful. In case it's not clear, it's defined in such away that you can have both a viins and a vicmd replacement. I've also neatened bin_vared by making it use the normal option handling; that didn't used to be possible because string argument handling was weak. Index: Doc/Zsh/contrib.yo =================================================================== RCS file: /cvsroot/zsh/zsh/Doc/Zsh/contrib.yo,v retrieving revision 1.30 diff -u -r1.30 contrib.yo --- Doc/Zsh/contrib.yo 13 Oct 2003 16:50:19 -0000 1.30 +++ Doc/Zsh/contrib.yo 5 Apr 2004 17:26:12 -0000 @@ -1328,6 +1328,11 @@ 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. ) findex(zcp) findex(zln) Index: Doc/Zsh/zle.yo =================================================================== RCS file: /cvsroot/zsh/zsh/Doc/Zsh/zle.yo,v retrieving revision 1.33 diff -u -r1.33 zle.yo --- Doc/Zsh/zle.yo 15 Dec 2003 22:45:27 -0000 1.33 +++ Doc/Zsh/zle.yo 5 Apr 2004 17:26:12 -0000 @@ -265,7 +265,8 @@ 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. @@ -292,6 +293,10 @@ 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. On exit, the previous keymaps will be restored. ) findex(zle) cindex(widgets, rebinding) Index: Functions/Misc/zed =================================================================== RCS file: /cvsroot/zsh/zsh/Functions/Misc/zed,v retrieving revision 1.6 diff -u -r1.6 zed --- Functions/Misc/zed 2 Apr 2001 13:04:05 -0000 1.6 +++ Functions/Misc/zed 5 Apr 2004 17:26:12 -0000 @@ -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 @@ 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 @@ 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' Index: Src/Zle/zle_keymap.c =================================================================== RCS file: /cvsroot/zsh/zsh/Src/Zle/zle_keymap.c,v retrieving revision 1.13 diff -u -r1.13 zle_keymap.c --- Src/Zle/zle_keymap.c 8 Mar 2004 11:44:14 -0000 1.13 +++ Src/Zle/zle_keymap.c 5 Apr 2004 17:26:13 -0000 @@ -169,8 +169,7 @@ 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 @@ 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 @@ 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. */ Index: Src/Zle/zle_main.c =================================================================== RCS file: /cvsroot/zsh/zsh/Src/Zle/zle_main.c,v retrieving revision 1.41 diff -u -r1.41 zle_main.c --- Src/Zle/zle_main.c 22 Mar 2004 19:51:17 -0000 1.41 +++ Src/Zle/zle_main.c 5 Apr 2004 17:26:13 -0000 @@ -987,6 +987,45 @@ 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 @@ 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 @@ 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 @@ /* 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 @@ /* 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 @@ 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 @@ 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 @@ 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), }; -- Peter Stephenson Software Engineer CSR Ltd., Science Park, Milton Road, Cambridge, CB4 0WH, UK Tel: +44 (0)1223 692070 ********************************************************************** This email and any files transmitted with it are confidential and intended solely for the use of the individual or entity to whom they are addressed. If you have received this email in error please notify the system manager. This footnote also confirms that this email message has been swept by MIMEsweeper for the presence of computer viruses. www.mimesweeper.com **********************************************************************