I've often found myself in such a frustrating situation, where I have to replace one keyword in the middle of a looong shell command that I just copied and pasted into the terminal (from StackOverflow or course 😅). Jumping over words with
Alt-Arrow doesn't work on all machines; how many left arrows and backspaces do I have to press, in order to replace that
username in that genius command I stole from that SO answer??
Finally, I sat myself down to do some research on how to properly practice Ninjutsu in the terminal. As it turns out, roaming inside that command line environment is not that difficult at all!
I'm primarily a Z-Shell user, so this article will be more focused on ZSH. The shortcuts we are going to see here, however, should mostly work in BASH as well (sorry I don't use FISH or other shells ).
Fun fact: shell key bindings actually defaults to "emacs mode"! You may have already discovered this if you are an emacs user. But for us mere mortals (or VIM-mortals), let's carry on and learn something new!
In fact, if you are more comfortable with VI/VIM, you can even switch to VI-bindings from the standard emacs one - use
set -o vito test it out! (You might need a plugin or two to give you hints whether you are in edit or normal mode though. Oh-My-Zsh has a plugin for this!)
Let's jump right in with the navigation shortcuts. Here's a little list of the useful ones:
|Ctrl-A||Jump to the beginning of line|
|Ctrl-E||Jump to end of line|
|Ctrl-B||Move back by one character|
|Ctrl-F||Move forward by one character|
|Meta-B||Jump back by one word|
|Meta-F||Jump forward by one word|
Note that what the Meta key actually is may vary on different setups (OS + terminal simulator). You might find
Alt working on your system as the Meta key, or the
Command key (if you are using iTerm on macOS, you can change Meta key binding in "Preferences"). However, if all fails, try pressing
ESC then release (not using it as a modifier), followed by the other key - this should work universally as well.
Here's a little list of default key bindings for editing:
|Ctrl-U||Cut current line*|
|Meta-W||Cut everything before the cursor (multi-line!)|
|Ctrl-K||Cut everything after the cursor on current line|
|Ctrl-W||Cut the previous word|
|Meta-D||Cut the next word|
|Ctrl-Y||Paste the stuff just cut (doesn't use OS clipboard)|
|Ctrl-_||Undo last change|
* This shortcut cuts everything before the cursor in BASH.
I never knew that I can undo in the terminal! How do you undo on Android BTW? 🤨
Something you might not know is that shells default to log every command that you've ever executed if you didn't opt out. For ZSH, that log book is kept under
~/.bash_history for BASH). This is actually a pretty neat feature, allowing us to search from previous commands and reuse them anytime to save time. (If you are feeling like to go incognito, you may wanna set
HISTSIZE = 1 in your
.zshrc to limit the history storing to only 1 record.
HISTSIZE = 0 doesn't seem to work though.)
To enter search mode, press
Ctrl-R. Now type the keyword that you are looking for. Press
Ctrl-R again to "find next".
You can exit the search mode anytime by trying to edit the current displaying search result, directly with the shortcuts we've mentioned above. Of course, you can abort with
Ctrl-C as well!
To iterate through the previous commands though, we don't need to enter search mode - just use
Ctrl-P to show the p-revious, or
Ctrl-N to show the n-ext line!
Instead of the
clear command, shortcut
Ctrl-L is another way to clear the screen. It also leaves the line you are working on intact, so if you are in the middle of typing a long command but suddenly find the littered terminal screen is super distracting, you can hit
Ctrl-L to clean up, without having to retype the command.
Ever wanted to type multiple lines into ZSH then execute in one single setting, just like copy & pasting some multi-line shell snippets?
Ctrl-V Ctrl-J will do the trick! (
Ctrl-V is "quoted-insert", which inserts instead of interprets the next input;
Ctrl-J prints the ASCII symbol
LF, the Unix "next-line".)
In ZSH, you can always obtain a list of the current key bindings with a simple
bindkey command. A BASH equivalent would be
In addition to the ability of switching to VIM mode, if are using ZSH and would like to customize your key bindings, you can easily do so by declaring stuff like
bindkey "^[X" zle-command (zle, The Z-Shell Line Editor is the line editor behind our beloved ZSH). A list of
zle-commands can be obtained with
I hope you have enjoyed this post, and have learned something useful, my fellow ninja! 🥳
Originally posted on my blog, where I publish random stuff on web dev, flutter and sometimes ML about every two weeks :)