Bash CTRL to move cursor between words/strings - bash

I am use to using the CTRL key to move faster when using the left and right arrow keys (goes to end of a word, instead of one char at a time).
Can I do that in bash somehow?
I could probably code it, but I was wondering if there is something easier / already done.

With the default readline key bindings, ALT+B goes back one word, ALT+F goes forward one word.
The default Ubuntu setup additionally provides CTRL+arrows like you're used to. These are in /etc/inputrc and specified as follows:
# mappings for Ctrl-left-arrow and Ctrl-right-arrow for word moving
"\e[1;5C": forward-word
"\e[1;5D": backward-word
"\e[5C": forward-word
"\e[5D": backward-word
"\e\e[C": forward-word
"\e\e[D": backward-word
Not sure why we need three of them...

As Thomas explained, you can add the bindings to /etc/inputrc.
Another alternative so it loads every time you log in, is putting them in ~/.bashrc like this:
#use ctl keys to move forward and back in words
bind '"\eOC":forward-word'
bind '"\eOD":backward-word'
I learned that you can use cat > /dev/null to look at the characters that your keyboard is sending, e.g., CTRL + right arrow shows:
^[OC
where ^[ is the same as \e so that's where the code comes from in the bind command.
You can also look up bindings like this:
bind -p | grep forward-word
All of this is pretty damn awesome and I'm glad I found out some more power of bash.

A .inputrc in your home directory will cause ctrl+left to stop working on Ubuntu (for example).
To get everything working, add the following to ~/.inputrc:
# Include system-wide inputrc, which is ignored by default when
# a user has their own .inputrc file.
$include /etc/inputrc
credit to f.kowal

Add $include /etc/inputrc
in ~/.inputrc
Worked for CentOS Linux release 8.2.2004 (Core)

Related

ZSH shell and CLion/PyCharm integration, movement around terminal

I'm trying to use zsh in the CLion terminal window (changed my shell to /bin/zsh)
But when I try to move around using Ctrl + Left, Ctrl + Right, Ctrl + E... I get the literal characters D, C and Ctrl + E opens the "Recent files" UI
Is there any way around this? I'd like to use the movement keystrokes as I can with bash.
Tempoz,
Check out the offical Zsh Line Editor doc and the Z-Shell Line Editor guide for tons of detail.
To start, you can see your current mappings by typing bindkey at your prompt. There are two start modes: emacs [default], and vi. If you want to use vi mode, add this to your ~/.zshrc
bindkey -v
and source it (or restart your shell, or restart your IDE). Check out how the bindkey output has changed.
If you decide you want to change or augment your key mappings, use bind in your ~/.zshrc to reassign, or add to your key map.
# Example key binding change
# bindkey key-sequence editor-command
bindkey '^Z' vi-kill-line
You will also probably want to fix your $PATH - all the JetBrains products do it incorrectly. See this answer: https://stackoverflow.com/a/51006003/1089228

Command-arrow for back and forward one word in PhpStorm terminal

I'm on OSX, and for some reason, when I do command - ← (back arrow) in the PhpStorm terminal I get a [D, while command - → (forward arrow) outputs a [C. What I want to do is jump forward and back one word.
In my OSX terminal these keypresses work as expected, and I can't find anywhere where they are set to output those characters. Does anyone have the answer to this conundrum?
Turns out that an answer for the same problem on iTerm also works for PhpStorm! The fix involves creating a new file named ~/.inputrc and then put the following code in it:
"\e\e[D": backward-word
"\e\e[C": forward-word
Here is the original link
If you are using zsh, add this to ~/.zshrc:
bindkey "\e\eOD" backward-word
bindkey "\e\eOC" forward-word

Looking for ALT+LeftArrowKey solution in zsh

I just recently switched from bash to zsh, however I miss my Alt+LeftArrowKey and Alt+RightArrowKey to go back and forth a word at a time.
Right now, if I press Alt+LeftArrowKey I go back a couple of letters and then I'm stuck. I won't go any further backwards and it won't back to the end of the line with Alt+RightArrowKey as I would expect. I can't even use the arrow keys to go to the end of the line, only to the second to last. Can't input new chars on the line either or indeed delete.
How do I get my beloved shortcut back?
I'm on Mac OS X using Terminal if that's important.
Run cat then press keys to see the codes your shortcut send.
(Press Ctrl+C to kill the cat when you're done.)
For me, (ubuntu, konsole, xterm) pressing Alt+← sends ^[[1;3D, so i would put in my .zshrc
bindkey "^[[1;3C" forward-word
bindkey "^[[1;3D" backward-word
(Actually I prefer to use Ctrl + arrow to move word by word, like in a normal textbox under windows or linux gui.)
Related question: Fix key settings (Home/End/Insert/Delete) in .zshrc when running Zsh in Terminator Terminal Emulator
For anyone using iTerm, regardless of shell
All of the solutions offered here take a backwards approach in my opinion. You're essentially telling your shell to listen for some esc sequence or other key binding you have set in your terminal, creating compatibility issues when you switch shells (If you SSH into some other shell, switch from BASH to ZSH, etc and you lose some if not all of your keybindings).
Most shells have a set of default sequences that come pre-bound. Furthermore, while they aren't 100% consistent, they're close enough. So the easiest way that I have found to create keybinding for a particular action in the shell is to tell your terminal application to bind to the default keybindings that are consistent across shells.
I wrote a compressive solution for getting your terminal to respond as close to native mac keybindings here
Open the iTerm preferences ⌘+, and navigate to the Profiles tab (the Keys tab can be used, but adding keybinding to your profile allows you to save your profile and sync it to multiple computers) and keys sub-tab and enter the following:
Move cursor one word left
⌥+← Send Hex Codes: 0x1b 0x62
Move cursor one word right
⌥+→ Send Hex Codes: 0x1b 0x66
And that should give you the desired behavior not just in ZSH, but also if you SSH into a server running BASH, irb/pry, node etc.
Adding the following to ~/.zshrc worked for me on OSX Mountain Lion.
bindkey -e
bindkey '[C' forward-word
bindkey '[D' backward-word
On MacOS High Siera 10.13.6 or Mojave 10.14.2 and using iTerm2 with ZSH
To move from words I have to put like this:
bindkey "\e\e[D" backward-word
bindkey "\e\e[C" forward-word
Another solutions doesn't work fo rme
For iTerm, go to where this screenshot shows and select "Natural Text Editing"
if you already had some key mappings it will ask below, select accordingly not to lose any special bindings you set before. however, if you don't remember adding any bindings or just started using iTerm (on this machine), you will be safe to choose "Remove"
Though not strictly answering your question, the default binding for forward-word and backward-word are alt-f resp. alt-b.
This works everywhere, does not require you to leave the home row, and has a nice mnemonic property (f=forward, b=back), while also being consistent with ctrl-f and ctrl-b being forward-character and backward-character.
Rip out your arrow keys!
To make it work for me I used this answer, however I had to swap the codes (left <-> right)
⌥+← Send Hex Codes: 0x1b 0x66
⌥+→ Send Hex Codes: 0x1b 0x62
and add the following to my ~/.zshrc
bindkey -e
bindkey "^[b" backward-word
bindkey '^[f' forward-word
On MacOS Monterey, use the following in ~/.zshrc to make SHIFT + Arrows jump words:
bindkey "^[[1;2C" forward-word
bindkey "^[[1;2D" backward-word
And this for Option + Arrows:
bindkey "^[^[[C" forward-word
bindkey "^[^[[D" backward-word
On Mavericks (10.9.4) the code is 1;5... so for binding alt with arrows I have my .zshrc using this:
bindkey "^[[1;5C" forward-word
bindkey "^[[1;5D" backward-word
You can use CTRL+V and then the command you want to use
in Yosemite use Rob's solution
In zsh, you can use the bindkey command to see keyboard shortcuts.
Use bindkey to explore options that are available without custom keybindings.
Namely ^[b to move backward a word and ^[f to move forward a word.
These keybindings work with Alacritty on Arch Linux, just add them to the ~/.zshrc file
bindkey -e
bindkey "^[[3~" delete-char # Key Del
bindkey "^[[5~" beginning-of-buffer-or-history # Key Page Up
bindkey "^[[6~" end-of-buffer-or-history # Key Page Down
bindkey "^[[H" beginning-of-line # Key Home
bindkey "^[[F" end-of-line # Key End
bindkey "^[[1;3C" forward-word # Key Alt + Right
bindkey "^[[1;3D" backward-word # Key Alt + Left
If you're using iTerm in CSI u mode, the bindings for your .zshrc end up being:
bindkey '^[[1;3D' backward-word
bindkey '^[[1;3C' forward-word
If you want iTerminal to respect Emacs style shortcuts like ^Mf and ^Mb for forward/back a word I found best way to use this tip:
Making iTerm to translate 'meta-key' in the same way as in other OSes

How can I make bash tab completion behave like vim tab completion and cycle through matching matches?

I've been meaning to find a solution for this for YEARS.
I am sooo much more productive in vim when manipulating files than bash for this reason.
If I have
file_12390983421
file_12391983421
file_12340983421
file_12390986421
In bash and type file_1->tab , it obviously lists:
file_12390983421 file_12391983421 file_12340983421 file_12390986421
And this is horrible and painful to work with.
The same sequence in vim will loop through the files one at a time.
Please someone tell me how to do this in bash, or if there is another shell that can do this, I'll switch tomorrow.
By default TAB is bound to the complete readline command. Your desired behavior would be menu-complete instead. You can change your readlines settings by editing ~/.inputrc. To rebind TAB, add this line:
TAB: menu-complete
For more details see the READLINE section in man bash.
For bash >= 4 you might like these settings. You can try them directly on the command-line, and put them in your ~/.bash_profile if you like them.
# If there are multiple matches for completion, Tab should cycle through them
bind 'TAB:menu-complete'
# And Shift-Tab should cycle backwards
bind '"\e[Z": menu-complete-backward'
# Display a list of the matching files
bind "set show-all-if-ambiguous on"
# Perform partial (common) completion on the first Tab press, only start
# cycling full results on the second Tab press (from bash version 5)
bind "set menu-complete-display-prefix on"
This setup is similar to Vim's set wildmode=longest:full:list,full
I pulled these settings from this question on the Unix & Linux site.
By the way, since you are here, here are some other great bindings:
# Cycle through history based on characters already typed on the line
bind '"\e[A":history-search-backward'
bind '"\e[B":history-search-forward'
# Keep Ctrl-Left and Ctrl-Right working when the above are used
bind '"\e[1;5C":forward-word'
bind '"\e[1;5D":backward-word'
This means if you type ssh<Up> it will cycle through previous lines where you ran ssh
If you don't like what you got, you can clear the line with Ctrl-K Ctrl-U
I pulled these settings from this question on AskUbuntu.
On top of
# cycle forward
Control-k: menu-complete
# cycle backward
Control-j: menu-complete-backward
you may also consider adding
# display one column with matches
set completion-display-width 1
This way you would preserve the current Tab functionality and make bash display the possibilities in one column. So instead of
file_12340983421 file_12390983421 file_12390986421 file_12391983421
you would get
file_12340983421
file_12390983421
file_12390986421
file_12391983421
P.S. You can get up to date readline library from this The GNU Readline Library website.
Thanks to #sth I found what works best for me:
To keep normal bash tab completion, and then use ctl-f to cycle through when needed using menu-complete
put this in your .inputrc file:
"\C-f": menu-complete
In my experience, the solution provided in sth's answer has never completely worked for me. TL;DR: Add set -o vi to your ~/.bashrc.
When using menu-complete in conjunction with vi keybindings, I have to make sure that my ~/.bashrc has:
set -o vi
It's never been enough for my ~/.inputrc just to have:
TAB: menu-complete
set editing-mode vi
set keymap vi
My guess is that somehow set editing-mode and set keymap are clobbering the TAB: ... setting, but I haven't looked into the documentation thoroughly to figure out why this is the case.

MSysGit Bash - how to enable Ctrl+Left / Right arrows?

Is there a way to enable Ctrl + ← / → keyboard shortcuts (go to previous / next word) in the Bash console installed with MSysGit?
At your Bash prompt, press Ctrl-v Ctrl-Left-Arrow and Ctrl-v Ctrl-Right-Arrow and make note of the output. You should see something like: ^[OD and ^[OC or similar. Add the following lines to your ~/.inputrc:
"\eOC": forward-word
"\eOD": backward-word
where you will substitute \e for escape (^[) and the rest of the characters you got (OD, OC or similar).
To re-read the file and make the changes active immediately, press Ctrl-x Ctrl-r.
I found this answer by tan on AskUbuntu, which worked for me after none of these answers did. I'll repost it here.
What is in your ~/.inputrc and /etc/inputrc? The minimum to get those keys working is, I think:
# mappings for Ctrl-left-arrow and Ctrl-right-arrow for word moving
"\e[1;5C": forward-word
"\e[1;5D": backward-word
"\e[5C": forward-word
"\e[5D": backward-word
"\e\e[C": forward-word
"\e\e[D": backward-word
If you have these in /etc/inputrc, the file needs to be included from ~/.inputrc, so check that it has the following line:
$include /etc/inputrc
Not really answering your question, but you can try ALT-F and ALT-B instead.
Adding to my ~/.inputrc
"\e[1;5C": forward-word
"\e[1;5D": backward-word
Was enough for me.
This worked for me in Windows 7:
Add this to the ~/.inputrc
Then restart the console and it should work for you.
This makes it so you can do either use
CTRL+← or CTRL+→
Or
ALT+← or ALT+→
## Windows msysgit
## Alt + right/left
"\e\e[C": forward-word ### Alt + right
"\e\e[D": backward-word ### Alt + left
## Ctrl + right/left
"\e[C": forward-word ### Ctrl + right
"\e[D": backward-word ### Ctrl + left
For those confused on why it is not working for the ctrl+Left-Arrow and ctrl+Right-Arrow.
This is because of a bug with windows 7, maybe others, and msys where the ctrl key would not be recognized (at least for my case).
To check if you are in the same situation, do what #Dennis say:
Open terminal
Make sure ctrl+v has not been remapped to something else
Press ctrl+v followed by ctrl+Left-Arrow to check the key sequence
Look at the output
Repeat with only pressing the Left-Arrow.
If they are identical, welcome to my world. You can now use Autohotkey to remap the keys or use the newer windows git bash.
I edited the file /etc/inputrc:
sudo gedit /etc/inputrc
and commented out the following lines:
$if term=rxvt
"\e[8~": end-of-line
"\eOc": forward-word
"\eOd": backward-word
$endif
Then I edited the file ~/.bashrc:
sudo gedit ~/.bashrc
and added the following lines at the bottom:
#### enable Ctrl+Left , Ctrl+Right keybindings:
bind '"\e[1;5C":forward-word' # Ctrl+Right
bind '"\e[1;5D":backward-word' # Ctrl+Left
It seems to work and, at least so far, without side effects.
(tested on Ubuntu GnomeShell Remix 12.04 AMD64)

Resources