No matter how you try to run from it, developers often find themselves on the command line so if you have always told yourself that the CLI sucks, then I think it is time to embrace it and stop having a terminal that looks like this:

Bland terminal

A bland default macOS terminal
Think of that more as sticking to the default terminal configuration rather than the actual look of the terminal. You could have such a minimalist but powerful terminal.

You may not care about the looks of your terminal as it does not directly affect your productivity. However, the terminal, shell, and utilities you use daily would work better with a better understanding of them.

Most of what follows applies to macOS and partially to other Unix derivatives.

The Terminal

macOS comes with Terminal.app, which is great enough as a console, but iTerm, the firebug of consoles, introduced many features before Terminal was improved. iTerm2 would be redundant now, but it improved on some features as Terminal tried to catch up. I have heard some developers say it is fast, but I do not really see a difference. What I love about iTerm is just the Tabs, as they look prettier than Terminal tabs.

iTerm console

iTerm

Terminal console

Terminal

Hyper.term is another terminal fancier than the previously mentioned, it is an electron app and is prone to performance problems which include high battery usage.

Hyper Terminal

With such aesthetic, hyper would make for a good terminal for demos. Can be used in screenshots or screencasts but not as a regular terminal.

Shells

There are countless shells, and bash is a very trusted one. It comes as the default shell on most macOS and Linux distributions. However, its lack of flexibility has made ZSH a choice for those who seek more control over the shell.

ZSH offers yet another set of options with its set of plugin/configuration managers. Prezto, Antigen, and Oh-my-zsh are the most common, and I cannot say which is best, as I have only used oh-my-zsh.

However, I would often hear prezto users say oh-my-zsh loads exhaustive plugins, which makes it slow, and that is not the case for me. The only default plugin enabled is the git plugin which is very useful (more on this soon). It also loads pretty fast for me. I could not care less about the 300ms difference in their load times.

Fish is another shell known for its autosuggest feature, but the problem with fish is its scripting language is far too different from common shells like bash and zsh. It also breaks in some cases, which makes it a less than great choice. The autosuggestions plugin for oh-my-zsh can provide just the same experience as fish.

Utilities

The tools and utilities you use with the right terminal and shell are what really boosts productivity. Utilities can also answer the question, "How productive have you been on the CLI?" Run this to get an answer to that:

$ history | awk '{print $2}' | sort | uniq -c | sort -nr | head

That will list your top 10 most used commands agnostic of what shell you may be on. If you do not feel cool about them, I will introduce some powerful utilities and how you can use them to full potential.

  • Autojump
  • Vim
  • Tmux
  • Git
  • Ack/Ag
  • FuzzyFinder
  • Say

Autojump

Autojump is basically a cd command that learns. If you often find yourself typing commands like:

$ cd ../../../ProjectRoot

or

$ cd ~/Downloads/Unzipped

then you need autojump which. With its short alias j, you can go to those directories like so

$ j ProjectRoot
$ j Unzipped

as long as you have once visited them with cd. j cannot jump to places it has not been before, so you need to have visited a directory at least once with cd.

You could also navigate GUI file managers using jo.

Autojump in use

Vim

Let's talk about vim

This list is once again biased as I am not talking about spacemacs or emacs since I do not use those. Instead, I would talk about the mainstream vim. The one a million users cannot exit and that is because this is about being productive. If you already know how to be productive with other CLI editors then go ahead.

I say CLI editors because I find myself most productive with them. Although, with IDEs bringing the command line in as part of their features, an IDE user might achieve the same level of productivity yet I would like to highlight the benefits of vim.

On macOS, you can set apps to be fullscreen, which I think is referred to as workstations in other OS. This gives a perceived reality of having multiple screens when you are not in a position to use multiple monitors or you simply cannot afford such setups. The benefit of this is you are locked out of every distraction in this single vim window.

Vim screenshot

Any editor can go full screen or even come with a distraction-free mode, but the benefit of this is that I am right in the shell. I could run any other CLI commands with !command or I could go into the shell within vim with !shell. With the right mappings in the vim configuration files, some of these system operations could also be bound to keys. You simply make a binding to something like !git status -sb.There are so many more benefits you could get with vim. Here is my vimrc for a glance.

Tmux

Tmux is a session manager and terminal multiplexer. With its windows, panes, and key bindings it complements vim. From the example of how you could lock yourself to a window with vim, you could even do more within this window by having tmux. Before Slack started chewing on productivity, developers would goof on the IRC for a few mins and ask questions all within the same window. If you are building an app with an interface like a web frontend or mobile/desktop application, you could move all distracting apps to a different workspace and just toggle between the terminal window and your app interface.

Git

Learning git properly beyond add, commit, push, clone can make an impact in how fast you git work done. It is called a version control software, but it could also be an automator and when used right, a great history preserver. In the post on debugging, we used git to debug and took advantage of its ability to automate the process. You can tune git up by adding hub and creating git aliases. If you have chosen to use oh-my-zsh, you may get the benefit of its nifty aliases with the git plugin. Some of which are:

alias ga='git add'
alias gc='git commit -v'
alias gcam='git commit -a -m'
alias gcsm='git commit -s -m'
alias gcb='git checkout -b'
alias gcf='git config --list'
alias gcl='git clone --recursive'
alias gclean='git clean -fd'
alias gpristine='git reset --hard && git clean -dfx'
alias gcm='git checkout master'
alias gcd='git checkout develop'
alias gcmsg='git commit -m'
alias gco='git checkout'
alias gcount='git shortlog -sn'
alias grt='cd $(git rev-parse --show-toplevel || echo ".")'
alias gsb='git status -sb'

Only listed some of my favorites. You should check out that alias list even if you are not using zsh.

Ack/Ag

Ack was made to grep beyond the abilities of the popular grep. Rather than just grepping through random file types, types can be specified with ack. It also obeys gitignores and ignore files for other VCS. If refactoring or tracking a bug from a stack trace, ack is extraordinary and it is not just me that thinks so

An example of where I use ack is when trying to find classes in BEM nested Sass files. People often complain about such syntax as:

.module{
  &__avatar{}
  &__title{}
}

and how they are difficult to search through as there may be other modules with the same BEM Element but different Block. With ack, it is as simple as:

$ ack --scss -l -Q .module | ack -x '&__avatar'

Just like everything else, ack has a competitor called the silver searcher aka ag that boasts of being faster than ack. Ack feels fast enough, and I have not worked on very large code bases to see it lag, but I use ag every once in a while. Both ag and ack can work through the Ack vim plugin.

Fuzzy Finder (FZF)

The best part about these tools is how they build upon each other. So far by using autojump over cd we can achieve better navigation within our project directories and around the entire filesystem, with the grt alias of oh-my-zsh we can jump to the root of a project, but that is still defeated by autojump. Then we have fzf kick autojump under the bus for navigating within a project.

Note that autojump is unbeatable for navigating all directories around the filesystem.

This shows how you can get to a project file easily with fzf

Fuzzy finder wildcarding

However, it does not end there for fzf. You could hook it up with ack or ag to improve its search performance over the default find it uses. You could also create vim mappings for it. I have a C-p mapping for it, and it makes file navigation within the project a lot faster than using project drawers. I still use NerdTree project drawer anyway.

Say

As a big lover of asynchronous communication and activities for easy multi-tasking, I find say to be useful for reading READMEs while I focus my hands and eyes elsewhere getting more work done. Once again Harry Roberts mentions just how good it is:


Here are some other [unsung heroes of the command line](https://hoelz.ro/blog/unsung-heroes-of-the-command-line) that can improve workflows: `jq`, `json_pp`, `uniprops`, `unichars`, `combine`, `cindex`, `csearch`, `sort`, `uniq`, `join`, `xargs`. Embrace the shell!