Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Bash: call script with customized keyboard shortcuts?

Lets say I have a script, "myscript.sh", with contents being simply echo $PWD. I'd like to bind somehow this script to a key combo in bash (gnome-terminal) - so that when I press this key combination, the output of "myscript.sh" is inserted ("pasted") at the cursor position in the terminal.

Apparently, bash history and line manipulation is handled by readline - and the references I got for bash keyboard shortcuts, do reference readline:

  • bash keyboard shortcuts
  • Bash Reference Manual: Bindable Readline Commands

I've also seen in Bash Reference Manual: Readline Init File Syntax that the key bindings for bash can be listed by using bind -p (see help bind [not 'man bind'] for more). So maybe this question would better be titled as "_binding macros to custom keyboard shortcuts in readline" :) But in any case, is what I want possible to do?

I guess an alternative would be to have the script be something like "pwd | xsel -b", and then I call it on terminal - and I can paste afterwards; but I'd still like a single keyboard shortcut instead, say like Ctrl-Alt-H (which seems to be not used for anything), which will immediately insert/paste script output when pressed.

Thanks in advance,
Cheers!

 
EDIT: Just to clarify - here is my use case where I'd like this facility. I'm usually cd'd in a project folder, usually named something like myproject-folder-0012a, which is under revision control by svn. And there is a bunch of these folders. So quite often, I do commits where the first word of the message is the directory name, as in:

svn ci -m "myproject-folder-0012a: here a commit message"

But that is what I don't like - first I type 11 characters, which go rather fast:

svn ci -m "

And then, I cannot use autocompletion to get the name (i'm inside the folder) - which means I either have to fully type it (no way :)), or I copy paste it from the prompt (which requires selection - press mouse, drag, release mouse; then Ctrl+Shift+C, and then Ctrl+Shift+V, plus any left/right keys if I miss allignment - plus deletions and such if I make the copy wrong).

Meaning - so much work, just to get the bloody folder name for a bloody commit message :( I'd MUCH rather press something like (say) Ctrl-Alt-H, and have the folder name automatically inserted at cursor position, and be done with it :)

My suggestion for xsel is only because I could put it into a "global" script - say symlink it as /usr/bin/myscript (and obviously, the contents of the script are echo $(basename $PWD) rather than just pwd for my needs), and then I could do:

$ myscript       # this puts directory name in clipboard
$ svn ci -m "[CTRL+SHIFT+V TO PASTE HERE]myproject-folder-0012a[NOW TYPE]: here a commit message"

... which sort of makes the workload less, but still - then I have to remember what the script name is, and call it, before I type the svn command (and I don't always remember that)... And still - I have to call a command, and then press a key combo; why shouldn't I just press a key combo once, and be done with it ??! :)

Well, hope this clarifies my problem a bit better ....

 
EDIT2: However, another reason why a bash keyboard shortcut would be useful, is that then I could also "paste/insert current directory name" not only in shell commands - but also in terminal programs, say like nano (where it would, arguably, be more difficult to use bash script or function expansion directly).

like image 427
sdaau Avatar asked Dec 29 '22 05:12

sdaau


1 Answers

Simple version:

This command at a shell prompt:

bind '"\ee": "${PWD##*/}\e\C-e"'

or this line added to your ~/.inputrc:

"\ee": "${PWD##*/}\e\C-e"

will cause Alt-e to insert the basename of the current directory on the command line. It requires that the default binding of the readline function shell-expand-line which is \e\C-e be present (this could be adapted if it's different). I'm also making the assumption that you're using Bash's emacs mode.

Unfortunately, it causes things that have already been typed to be expanded as well. One of the affects of this is that after having typed:

svn ci -m "

and pressing Alt-e, the quotation mark will have disappeared. There are a couple of ways to deal with this.

One, assume that all you'll lose is the quote and either manually add it back or have the readline macro add it for you:

bind '"\ee": "${PWD##*/}\e\C-e\eb\"\C-e"'

which just isn't very satisfactory.

Advanced version:

Or, two, kill the line, do the insertion, then yank the line back:

bind '"\ee": " \C-u \C-a\C-k${PWD##*/}\e\C-e\C-y\C-a\C-y\ey\b"'

or

bind '"\ee": " \C-u \C-a\C-k${PWD##*/}\e\C-e\C-y\C-a\C-y\ey\b\ef\C-f"'

This leaves the rest of the line intact (nothing else is expanded or deleted), but it uses the kill ring, so it may leave it in a state that's different than you expect (if you're using it). It also inserts a space after the inserted directory name (the spaces in the macro are used to ensure that older kill-ring contents are not regurgitated if the macro is executed at the beginning or end of the line). The macro should work regardless of the position of the cursor in the line. The insertion will be made at the cursor's position, leaving the cursor in the same position [in the first version].

Edit: The second version leaves the cursor after the dirname and space that are inserted.

Edit 2:

The readline function shell-forward-word (unbound) does a better job than forward-word (\ef) for this. You can make use of that like this:

bind '"\ew":shell-forward-word'
bind '"\ee": " \C-u \C-a\C-k${PWD##*/}\e\C-e\C-y\C-a\C-y\ey\b\ew\C-f"'

By the way, you should know that Bash keyboard shortcuts are not active in other programs such as nano.

like image 114
Dennis Williamson Avatar answered Jan 11 '23 21:01

Dennis Williamson