Zsh Mailing List Archive
Messages sorted by: Reverse Date, Date, Thread, Author

Re: Multi-level keybinding?



On Dec 20,  4:40pm, Richard Hartmann wrote:
}
} I want to offer users of my RC files a short overview of what
} they can do with <Ctrl-E foo>.

Ctrl-e is normally bound to "end-of-line" which seems like a pretty
commonly-used operation to choose to override ... unless you're in
vi-mode, I suppose.

} Ideally, I would want to
} 
}   bindkey '^E' binding_overview
}   bindkey '^Ee' push_line
}   bindkey '^Ei' insert-unicode-char
} 
} etc etc.

Reading this I'm not sure what output you want from "binding_overview".
Since ^E is a prefix of other keys, it's only going to get invoked if
they press ^E and then wait a bit.  Once binding_overview does get
control, is it intended to immediately produce a listing of all the
available bindings, or to wait for a key and then explain that one?  If
the latter, is it your intention that they retype the ctrl-e or do you
mean e.g. to have <ctrl-e><pause><i> explain insert-unicode-char?

} Of course, I could make the binding_overview
} widget accept a letter and emulate 'proper' keybindings,
} but I would prefer a solution within the shell.

I'm also confused about the difference between "make the widget" do
something and "within the shell".  You mean you'd prefer that there
is a built-in solution to one you'd have to script yourself?

Have a look at the doc for the following widgets:

    describe-key-briefly
    read-command

The implementation of describe-key-briefly is approximately the same
as this shell code:

    describe-key-briefly() {
      zle -R -c 'Describe key briefly:'
      zle read-command
      zle -M "${(qqqV)KEYS} is $REPLY"
    }
    zle -N describe-key-briefly

However, there's a problem with this:  Because ^E is a prefix of some
of the other keys you want to describe, it will be very difficult for
the user to type e.g. ctrl-e i fast enough to get the widget to ever
respond with anything other than:	"^E" is describe-key-briefly
(and the vale of $KEYTIMEOUT is only consulted before the widget ever
begins executing, so you can't alter it locally within the widget).

So at least for now you probably need to bind this to a sequence that
is not a prefix of any other binding.

If you want to dump all the bindings, the only way is to invoke the
bindkey command:

    binding_overview() {
      zle -R -c '' ${(f)"$(bindkey)"}
    }

If you want only the bindings that begin with ^E, then:

    binding_overview() {
      zle -R -c '' ${(f)"$(bindkey | grep '^\"\^E')"}
    }

You can probably run with this from here.



Messages sorted by: Reverse Date, Date, Thread, Author