Zsh Mailing List Archive
Messages sorted by:
Reverse Date,
Date,
Thread,
Author
Re: change color depending on vi-mode
- X-seq: zsh-workers 22169
- From: Peter Stephenson <p.w.stephenson@xxxxxxxxxxxx>
- To: zsh-workers@xxxxxxxxxx
- Subject: Re: change color depending on vi-mode
- Date: Tue, 24 Jan 2006 21:01:51 +0000
- In-reply-to: <1060123161718.ZM28725@xxxxxxxxxxxxxxxxxxxxxxx>
- Mailing-list: contact zsh-workers-help@xxxxxxxxxx; run by ezmlm
- References: <slrndt9eu5.pr3.f.braennstroem@xxxxxxxxxxxxxxxxxxxxx> <1060123161718.ZM28725@xxxxxxxxxxxxxxxxxxxxxxx>
On Mon, 23 Jan 2006 16:17:18 +0000
Bart Schaefer <schaefer@xxxxxxxxxxxxxxxx> wrote:
> The short answer is that the only way to do it is to create your own
> widget functions for all of the vi commands that change modes. There
> is no "callback" associated with changing the keymap that can be used
> to update the prompt.
It's easy to add, however (redirected to zsh-workers).
The following function provides a simple example, but I'm sure there's a
better one for inclusion with the supplied Zle functions. (Bits of
http://www.gott-gehabt.de/800_wer_wir_sind/thomas/Homepage/Computer/zsh/vi-showmode
could be included; it looks like that works perfectly well but
redefining every vi widget is a bit heavy going and this is more
general.) I tried it with "/" within vi command mode and it looks like
the mechanism is fairly robust, although I wouldn't be surprised if
there were gotchas.
I'm not prepared to hold my breath until we have get and set advice
functions for variables...
By the way, this is partly because I realise I've been extremely slow
getting out another 4.3 test release and there's nothing really hindering
it. I've been fairly busy.
zle-keymap-select() {
local showcmd="<C>"
if [[ $KEYMAP = vicmd ]]; then
if [[ $PS1 != "<C>"* ]]; then
PS1="$showcmd$PS1"
zle reset-prompt
fi
else
if [[ $PS1 = "<C>"* ]]; then
PS1=${PS1##$showcmd}
zle reset-prompt
fi
fi
}
zle -N zle-keymap-select
The name chosen isn't entirely to be illogical, it's because I expect
functions of this sort to have a vaguely object-oriented naming
convention along the lines of <module>-<object>-<action>. Compare
zsh-mime-handler and zsh-mime-setup.
Index: Doc/Zsh/zle.yo
===================================================================
RCS file: /cvsroot/zsh/zsh/Doc/Zsh/zle.yo,v
retrieving revision 1.48
diff -u -r1.48 zle.yo
--- Doc/Zsh/zle.yo 24 Nov 2005 10:25:34 -0000 1.48
+++ Doc/Zsh/zle.yo 24 Jan 2006 20:46:27 -0000
@@ -763,8 +763,8 @@
subsect(Special Widget)
-There is one user-defined widget which is special to the shell.
-If it does not exist, no special action is taken. The environment
+There are a few user-defined widgets which are special to the shell.
+If they do not exist, no special action is taken. The environment
provided is identical to that for any other editing widget.
startitem()
@@ -780,6 +780,19 @@
(The command inside the function sets the keymap directly; it is
equivalent to tt(zle vi-cmd-mode).)
)
+tindex(zle-keymap-select)
+item(tt(zle-keymap-select))(
+Executed every time the keymap changes, i.e. the special parameter
+tt(KEYMAP) is set to a different value, while the line editor is active.
+Initialising the keymap when the line editor starts does not cause the
+widget to be called.
+
+The value tt($KEYMAP) within the function reflects the new keymap. The
+old keymap is passed as the sole argument.
+
+This can been used for detecting switches between the vi command
+(tt(vicmd)) and insert (usually tt(main)) keymaps.
+)
enditem()
sect(Standard Widgets)
Index: Src/Zle/zle_keymap.c
===================================================================
RCS file: /cvsroot/zsh/zsh/Src/Zle/zle_keymap.c,v
retrieving revision 1.23
diff -u -r1.23 zle_keymap.c
--- Src/Zle/zle_keymap.c 28 Oct 2005 17:42:07 -0000 1.23
+++ Src/Zle/zle_keymap.c 24 Jan 2006 20:46:28 -0000
@@ -400,8 +400,24 @@
km = openkeymap(name = ".safe");
}
if(name != curkeymapname) {
- zsfree(curkeymapname);
+ char *oname = curkeymapname;
+ Thingy chgthingy;
+
curkeymapname = ztrdup(name);
+
+ if (oname && zleactive && strcmp(oname, curkeymapname) &&
+ (chgthingy = rthingy_nocreate("zle-keymap-select"))) {
+ char *args[2];
+ int saverrflag = errflag, savretflag = retflag;
+ args[0] = oname;
+ args[1] = NULL;
+ errflag = retflag = 0;
+ execzlefunc(chgthingy, args);
+ unrefthingy(chgthingy);
+ errflag = saverrflag;
+ retflag = savretflag;
+ }
+ zsfree(oname);
}
curkeymap = km;
return 0;
--
Peter Stephenson <p.w.stephenson@xxxxxxxxxxxx>
Web page still at http://www.pwstephenson.fsnet.co.uk/
Messages sorted by:
Reverse Date,
Date,
Thread,
Author