12

In ZSH, how can I use bindkey to bind a key sequence to a script?

3 Answers 3

12

I think you do not need widget for that:

bindkey -s '\eb' '/path/to/script.sh\n' 

From zsh docs:

As well as ZLE commands, key sequences can be bound to other strings, by using ‘bindkey -s’.

4
  • 3
    That doesn't bind Alt-B to the script, that causes /path/to/script.sh\n to be inserted as if typed. For instance if you type Alt-B after having entered echo , that will just run the echo /path/to/script.sh command and get you back to an empty prompt (with the echo you had entered earlier gone). Aug 13, 2016 at 7:21
  • 1
    Yes, you are right. But still inserted as if typed is enough in some use cases.
    – suside
    Aug 14, 2016 at 9:22
  • 5
    Add an enter at the end of the string and the script will get executed after being inserted, bindkey -s '\eb' '/path/to/script.sh^M'
    – mihai
    Jun 3, 2017 at 22:38
  • 1
    @mihai Thanks for your comment. It works perfectly.
    – jdhao
    Jun 13, 2019 at 12:49
8

You can define a widget that calls your script:

my-script_widget() my-script its args
zle -N my-script_widget
bindkey '\ej' my-script_widget

But why would you want to call your script directly from the zle?

If it displays anything, it will mess up the display. If you want its output displayed as other widget messages, you can do:

my-script_widget() zle -M "$(my-script its args)"

Or if you want the output inserted at the cursor:

my-script_widget() LBUFFER+=$(my-script its args)
1
  • Do you place this code in ~/.zshrc - or another location?
    – Seamus
    Dec 28, 2022 at 4:46
1

To expand a bit on @suside's answer:

Since bindkey -s just sends key sequences, if theres already something on your prompt and you try and use the binding, it just types it in after whats already at the prompt. This can be fixed by sending kill-whole-line to clear the prompt before typing your command/script in.

kill-whole-line is typically bound to ^u (Ctrl+U), see docs. If its not, you can bind it with:

bindkey '^u' kill-whole-line

Then, you can do:

bindkey -s '\eb' '^u/path/to/script.sh^M'

which binds Alt+b to kill the current line before typing your characters, then sending ^M (newline).

0

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .