Is there a way to combine two operations into one keybinding (dont think would work with function).
This is what I'd like to do:
I'd like a keybinding (say Ctrl-X) to -
I know that I can (in ~/.inputrc
) specify
C-X: "ls"
)C-SPACE: menu-complete
)But I am not sure how to put these together
The trick to this is to call functions which rebinds your keys. In my example I'll use C-b to insert text and to call menu-complete, instead of C-x. You'll have to sacrifice a key, in my example C-t
In .bashrc, or a bash file to be sourced
set_Cb_to_insert_text() {
bind '"\C-m": accept-line'
bind '"\C-b":"ls \C-t1"'
bind -x '"\C-t1":set_Cb_to_complete'
}
set_Cb_to_complete() {
bind '"\C-m":"\C-t2\C-t3"'
bind '"\C-b": menu-complete'
bind '"\C-t2": accept-line'
bind -x '"\C-t3":set_Cb_to_insert_text'
}
set_Cb_to_insert_text
How this works:
With bind
, you can bind keys to do one of three things, but no combination of them:
bind '"key": command'
bind '"key":"keystrokes"'
bind -x '"key": shell-command'
So if you want to combine these three things, you'll need to bind them each to a separate combination of keystrokes (in my example C-t{1,2,3}) and bind a key to execute all these keystrokes.
In the example:
C-b first inserts ls
and 'presses' C-t1, which executes set_Cb_to_complete
, which in turn rebinds C-b to menu-complete
. It also rebinds C-m, carriage return, or Enter, because it now needs to do two things: Accept the line, and reset C-b to insert ls
, by calling the set_Cb_to_insert_text
function, which also resets Enter to it's normal use.
The reason I said that C-t had to be "sacrificed", is that if you press C-t, readline will wait to see if you are going to press 1, or 2, or any of the bound key sequences, before it takes any action. But when you first have put C-t to this use, you can use it as an initial key for a huge amount of keystrokes to cover all your readline trickery.
Piece of advice: While you are writing and testing these, bind an alternate key to accept-line
, because suddenly something breaks the chain at the wrong place, and you are stuck in a terminal without a way to execute commands :)
This might work for you:
"\ex": menu-complete
"\ez": "ls \ex"
Include these lines in your ~/.inputrc
file.
These lines set Alt-x to menu-complete
and Alt-z to ls
space
menu-complete
. This will give you the first file in the directory and use Alt-x to cycle through the remainder one at a time.
See here for more examples of macros.
Checkout the readline commands by invoking bind -p
or bind -P
and bind -s
will show the macros you already have. See here for the bind command also you can make one off macros too, see here. Lastly check that the .inputrc
file is being read, I had trouble because the environmental variable was set to /etc/Inputrc
and my personal version was never being invoked.
BTW steer clear of Control-x as it is already in use for many readline commands.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With