10 Zsh Tips & Tricks: Configuration, Customization & Usage

As web developers, the command line is becoming an ever more important part of our workflow. We use it to install packages from npm, to test API endpoints, to push commits to GitHub, and lots more besides.

My shell of choice is zsh. It is a highly customizable Unix shell, that packs some very powerful features such as killer tab completion, clever history, remote file expansion, and much more.

In this article I’ll show you how to install zsh, then offer ten tips and tricks to make you more productive when working with it.

This is a beginner-level guide which can be followed by anybody (even Windows users, thanks to Windows Subsystem for Linux). However, in light of Apple’s announcement that zsh is now the standard shell on macOS Catalina, mac users might find it especially helpful.

Let’s get started.

Installation

I don’t want to offer in-depth installation instructions for each operating system, rather some general guidelines instead. If you get stuck installing zsh, there is plenty of help available online.

At the time of writing the current zsh version is 5.7.1.

macOS

Most versions of macOS ship with zsh pre-installed. You can check if this is the case and if so, which version you are running using the command: zsh --version. If the version is 4.3.9 or higher, you should be good to go (we’ll need at least this version to install Oh My Zsh later on). If not, you can follow this guide to install a more recent version of zsh using homebrew.

Once installed, you can set zsh as the default shell using: chsh -s $(which zsh). After issuing this command, you’ll need to log out, then log back in again for the changes to take effect.

If at any point you decide you don’t like zsh, you can revert to Bash using: chsh -s $(which bash).

Linux

On Ubuntu-based distros, you can install zsh using: sudo apt-get install zsh. Once the installation completes, you can check the version using zsh --version, then make zsh your default shell using chsh -s $(which zsh). You’ll need to log out, then log back in for the changes to take effect.

As with macOS, you can revert back to Bash using: chsh -s $(which bash).

If you are running a non-Ubuntu based distro, then check out the instructions for other distros.

Windows

Unfortunately, this is where things start to get a little complicated. Zsh is a Unix shell and for it to work on Windows, you’ll need to activate Windows Subsystem for Linux (WSL), an environment in Windows 10 for running Linux binaries.

There are various tutorials online explaining how to get up and running with zsh in Window 10s. I found these two to be up-to-date and easy to follow:

Note that it is also possible to get zsh running with Cygwin. Here are instructions for doing that.

First Run

When you first open zsh, you’ll be greeted by the following menu.

Zsh first run menu

If you select (1) you’ll be taken to a menu that allows you to configure history, keybindings and a bunch of other things. However, I suggest selecting (2) which will create a configuration profile with the recommended default settings.

Locating the Configuration File

Now let’s have a look at the file that zsh just created. Enter your home directory and open the .zshrc file in your editor of choice. This file is run whenever you start zsh and is the place where any custom configuration lives.

Note: file names that begin with a dot are hidden by default on most operating systems, so you’ll need to make it visible before you can edit it. If you’re not sure how, search for “Show hidden dot files mac/Linux etc”.

We can demonstrate how this file works by creating an alias. In their simplest form, aliases are terminal shortcuts for regular commands. Add the following to the bottom of .zshrc and save the file:

alias myip="curl http://ipecho.net/plain; echo"

Restart your shell (for example, by closing it then opening it again), then type myip. Providing you have the cURL program installed, you should see your current public IP address output to the terminal. If you’d like to experiment more with aliases, check out 7 Super Useful Aliases to make your development life easier.

Shut the terminal by typing exit, then locate the .zsh_history file, which is also in your home directory. This is where zsh stores a list of your previous terminal commands. Currently it should contain two lines, namely myip and exit.

Note: We’ll be reloading our shell several times through out the tutorial. You can also do this with a command: source ~/.zshrc.

Check Your Progress

By this point you should have zsh installed and set as your default shell. If you experience any problems, try creating a topic on SitePoint’s forums and ask for help there.

Now let’s get into some tips.

1. Install Oh My Zsh

If you only follow one of these tips, it needs to be this one.

Oh My Zsh is a community-driven framework for managing your zsh configuration and comes bundled with thousands of helpful functions, helpers, plugins and themes. Many of the following tips will rely on you having this installed.

As is explained on the project’s homepage, you can install it using cURL or wget.

sh -c "$(curl -fsSL https://raw.github.com/robbyrussell/oh-my-zsh/master/tools/install.sh)"
sh -c "$(wget https://raw.github.com/robbyrussell/oh-my-zsh/master/tools/install.sh -O -)"

This assumes you have git installed, which you hopefully do already. If not, you can grab it from the project’s homepage.
Oh My Zsh post install message

As you can see, from the post installation message, Oh My Zsh created a backup of your .zshrc file, then replaced it with its own version. This means that you’ll need to copy over any custom configuration (such as our myip alias) to your new .zshrc file.

2. Select a Theme

If you spend a lot of time in the terminal, it’s worth investing some effort in making it visually appealing. Luckily Oh My Zsh ships with a whole bunch of themes.

If you look in the ~/.zshrc file for the ZSH_THEME variable, you’ll find it’s set to robbyrussel. This is the default theme that the creator of Oh My Zsh uses.

To install a different theme, pick one from the link above and change the value of the ZSH_THEME variable, before restarting your shell. For example, setting ZSH_THEME="avit" will cause Oh My Zsh to use the avit theme.

You might also like to alter the color scheme for your terminal. On my Linux machine, I could do this via Edit > Preferences > Colors. Removing the tick from Use colors from system theme, then selecting Solarized dark as a scheme, gives me a very appealing result in next to no time.

Avit theme on Oh My Zsh

Notice how the theme recognizes that it’s in a git repo, tells me which branch I’m on and displays a green tick to let me know that everything is up to date.

I encourage you to have a look through the available themes and find one that suits you.

Troubleshooting

When I was testing this on WSL, I was seeing broken characters in my terminal, as soon as I installed Oh My Zsh. To remedy this I had to install the Powerline fonts and tell my terminal to use them.

git clone https://github.com/powerline/fonts.git

Then open an admin PowerShell, navigate to the root of the repo and run:

.\install.ps1

If PowerShell blocks you from running the script, then try setting the ExecutionPolicy as per this StackOverflow answer. Once the fonts are installed, be sure to set it back again.

Finally, right click on the terminal’s title bar, choose Properties > Font and make sure a Powerline font is selected. In testing, Deja Vu Sans Mono for Powerline worked well for me.

Also note that a couple of the themes require Powerline fonts, regardless of the operating system. We’ll look at installing one of these themes (Agnoster) towards the end of the article.

3. Working with History

One of my favorite Oh My Zsh features is the way that it lets you search through your history. Imagine that the contents of .zsh_history look like this:

cd Desktop
mkdir my-project
cd my-project
npm init -y
mkdir {src,build}
touch index.js

If you are in the terminal and press the key, you would expect to cycle through each of those history entries one by one, right? No surprise there.

However, Oh My Zsh allows you to enter the beginning of a command, then press the key to cycle through matching entries. So, in the above example if you entered “mkdir” and then pressed the key, you would see “mkdir {src,build}” displayed. If you pressed it again, you would then see “mkdir my-project”.

I use this feature all the time. For instance, when I want to ssh into a server and can’t remember the exact credentials, I just enter “ssh” and can cycle through recent connections until I find the right one. Or, when I can’t remember the exact syntax of a command, I can just enter the first few characters and cycle through any matches.

4. Autosuggestions FTW!

Another great feature of Oh My Zsh is plugins. These add new features to your shell and augment its functionality.

Oh My Zsh ships with hundreds of plugins for every conceivable use and we’ll look at some of these later in the article. In this section however, I’d like to introduce you to a third party plugin called autosuggestions. This suggests commands as you type based on history.

To install, you need to clone its repository into $ZSH_CUSTOM/plugins. By default this is ~/.oh-my-zsh/custom/plugins.

git clone https://github.com/zsh-users/zsh-autosuggestions ${ZSH_CUSTOM:-~/.oh-my-zsh/custom}/plugins/zsh-autosuggestions

Once done, to activate it, hop into the ~/.zshrc file and uncomment the following line:

# plugins=(git)

Then replace git with zsh-autosuggestions

plugins=(zsh-autosuggestions)

Restart your shell and you will notice that as you type a command, Oh My Zsh will make suggestions based on your history. If the suggestion is the one you are looking for, press the key to accept it. A real time saver!

Autosuggestions with Oh My Zsh

5. File Navigation with Oh My Zsh

Another awesome thing about Oh My Zsh, is how easy it makes it to navigate around your machine.

For example, when you want to change directory, it is not necessary to enter the cd command, i.e. cd Desktop just becomes Desktop. And that works with paths, too — you can enter /home/jim/Desktop and end up right where you wanted to go.

Oh My Zsh has great autocomplete, too. Once you have started typing a path, you can press TAB to have it expand a list of all possible folders you can navigate to. If you continue tabbing, you can move through this list until you select a folder by pressing Return. Pressing TAB again after that will restart the process.

Oh My Zsh file navigation with TAB completion

Finally, it’s worth mentioning that Oh My Zsh provides a number of commands and aliases for working with, and navigating directories. For example, typing ... will move you up two directories and typing take <dir-name> will create a new directory and navigate to it. Oh My Zsh also supports dynamic path completion, so typing (for example) /h/j/De and pressing Tab will expand the path to /home/jim/Desktop. Cool, eh?

Bonus Tip: If you’re feeling lazy, you can just drag and drop a folder onto the terminal window and the path will be expanded for you.

6. Navigate to Anything Using z

z is a handy plugin that builds a list of your most frequent and recent folders (it calls these “frecent”) and allows you to jump to them with one command. This is often much more convenient than having to tab through a nested folder structure.

To install the plugin, all you have to do is add it to your .zshrc file like so:

plugins=(z zsh-autosuggestions)

Then restart your terminal.

Once installed, z will have a short learning phase as it observes you navigating around your PC with the terminal. After a while however, you will be able to type z followed by any word that is in your desired directory path. The plugin will use fuzzy matching to figure out which folder you want to go to and expand the path accordingly. If there is more than one possibility you can tab through the options as described in the previous tip.

This might not sound like a big deal, but you’ll be able to open a shell, type z my-project and have it expand the path to /home/jim/files/some/deeply/nested/directory/or/other/my-project. Then when you’re in that directory, you can type z my-other-project and have it expand the path to /var/www/html/projects/top/secret/my-other.project.

Note: the first time I ran z, and attempted to change directory, I got the error
_z_dirs:2: no such file or directory: /home/jim/.z. This was a one off, as z apparently needed to make a .z file in my home directory. If you run into any problems, this article has some suggestions.

7. Working with git

Zsh includes some basic git integration out of the box. For example, if you type git and press the Tab key, zsh will helpfully spit out a long list of possible git commands. This becomes slightly more useful if you type git, followed by the first couple of letters of the command you are looking for. For example git a + Tab produces:

add        -- add file contents to index
am         -- apply patches from a mailbox
apply      -- apply patch to files and/or to index
archimport -- import an Arch repository into git
archive    -- create archive of files from named tree

Things start to get more interesting when you install the Oh My Zsh git plugin.

plugins=(git z zsh-autosuggestions)

This provides a whole bunch of aliases, as well as some useful functions for working with git. Some of the ones I use frequently are:

  • gaagit add all
  • gdcagit diff --cached
  • gpgit push
  • gpf!git push --force
  • grhhgit reset --hard
  • gstgit status

You could also create an alias for several commands at once, by adding the following to your .zshrc file:

function acp() {
  git add .
  git commit -m "$1"
  git push
}

Now, when you’re in a git repo, typing acp "a commit message" will add all changed files, commit them with whatever commit message you specified, then push them to your remote. Credit for this idea goes to Ali Spittel.

8. Get Instant Feedback on the State of a git Repo

At the top of the article we activated a theme called avit. When in a git repo, this theme will display the branch name, as well as a cross or tick indicating whether everything branch is up-to-date. I love being able to see this information at a glance and it is definitely a big step up from having to type git status all the time.

There are a couple of themes, however, that display this information in a more intuitive way. My favorite is Agnoster. Let’s install that now.

For Agnoster to render arrows and git icons correctly, you will likely need to install a Powerline-patched font. WSL users can do this by following the instructions in the troubleshooting section above. For Mac and Linux users, installation instructions can be found in the project’s repo.

Mac users on High Sierra or later may need to perform some additional work to get these fonts to display. Unless you are on Catalina, this method is recommended. Catalina users will need to install a patched font and select it in their terminal settings.

To test if your terminal can display all of the necessary characters. run the following command:

echo "\ue0b0 \u00b1 \ue0a0 \u27a6 \u2718 \u26a1 \u2699"

The result should look like this:

Powerline fonts required for the Agnoster theme

After that, enable the theme by changing the following line in your .zshrc file:

ZSH_THEME="agnoster"

and restarting the terminal. Once Agnoster is up and running, you’ll have a more intuitive view of the status of any git repository. You’ll also receive visual feedback as to whether the previous command succeeded or failed, and whether you are working with elevated privileges.

Up and running with the Agnoster theme

Tip If you don’t like the user@host part of the prompt, you can make this disappear by adding DEFAULT_USER=your_user_name to the .zshrc file.

9. Plugins, Plugins, Plugins

As mentioned, Oh My Zsh ships with a lot of plugins. You really should look through these and invest some time learning those that will help your workflow. To get you started, here are some popular ones to be aware of:

  • cloudapp – uploads files and piped contents to the Cloudapp service. Outputs and copies the resultant URL to the clipboard.
  • command-not-found – if a command is not recognized in the $PATH, this will use Ubuntu’s command-not-found package to find it or suggest spelling mistakes (Only for Ubuntu and openSUSE).
  • node – open the Node API, for your current version, in your browser.
  • npm – adds autocompletion to npm.
  • sudo – hitting ESC twice puts sudo in front of the current command, or the last one if the command line is empty.
  • vscode – makes interaction between the command line and the code editor easier.

10. Key Combos

This is not a zsh specific tip, but to wrap up I wanted to make you aware of these five time-saving key combos.

  • Ctrl + U – delete from the cursor to the start of the line.
  • Ctrl + K – delete from the cursor to the end of the line.
  • Ctrl + W – delete from the cursor to the start of the preceding word.
  • Alt + D – delete from the cursor to the end of the next word.
  • Ctrl + L – clear the terminal.

If you can memorize those, you’ll be surprised at how often they come in handy.

Conclusion

In this post I have demonstrated how to install zsh and set it as your default shell. I have also showed how to get the most out of your new terminal with the Oh My Zsh framework. It’s my hope that if you give these a try for a couple of weeks, you’ll wonder how you ever did without.

And don’t forget, if you have any problems with any of this, you can hop over to SitePoint forums and ask for help there. I’d also be happy to hear if I missed anything out — for example, your favorite theme, plugin, alias, or productivity tip.

You can hit me up either on the forums or on Twitter.

Comments are not currently available for this post.