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 path/to/file
or 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 vi
to 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!)
Navigation
Let's jump right in with the navigation shortcuts. Here's a little list of the useful ones:
Shortcut | Action |
---|---|
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.
Editing
Here's a little list of default key bindings for editing:
Shortcut | Action |
---|---|
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? 🤨
Searching and History
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 logbook is kept under ~/.zsh_history
(or ~/.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!
More Cool Stuff
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".)
Even Cooler - DIY! 😋
In ZSH, you can always obtain a list of the current key bindings with a simple bindkey
command. A BASH equivalent would be bind -P
.
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-command
s can be obtained with zle -al
.
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 every two weeks or so.
You can also find me on Twitter @hexrcs :)
Top comments (1)
CTRL-R is one of my favourite :)