I spend a lot of time on the terminal. I started with vanilla terminals on Ubuntu and macOS. Later I learned about terminals with a few "batteries" included like iTerm2 and HyperJS. I have also used tmux extensively before, but ended up switching a few months later to use window splitting from iTerm2 and also profiles, which can login to a shell session automatically. Well, enough of history.
This post will introduce you to a basic shell configuration. Ok, it is not basic. However, for me it is the difference between bearing and loving my terminal setup. Topics I will talk about are the following:
- oh-my-zsh
- The Best Zsh Plugins
- Other Zsh Plugins
- default EDITOR
- Fancy (and fast) command line tools
- Spacemacs
- File Conversion
I will build this configuration starting from a vanilla Ubuntu 18.04 installation.
If you just want to check the dotfile: check this gist.
Oh My Zsh
I used vanilla bash for quite a few years without even caring about what it was. I found out oh-my-zsh, which had incredible features, and switched to zsh just to use it. The end. You may be able to find similar packages for bash (oh-my-bash is a thing), but I never tried them.
I can't live without oh-my-zsh mainly for two reasons:
- Themes
- Aliases Some examples of aliases I love are presented below. You can see just how much characters I avoid typing.
ga='git add'
gc='git commit -v'
gc!='git commit -v --amend'
gca='git commit -v -a'
gca!='git commit -v -a --amend'
gcb='git checkout -b'
gcm='git checkout master'
gcd='git checkout develop'
gd='git diff'
gdca='git diff --cached'
gds='git diff --staged'
gf='git fetch'
gfa='git fetch --all --prune'
gfo='git fetch origin'
gl='git pull'
glg='git log --stat'
gm='git merge'
gp='git push'
gpf!='git push --force'
gss='git status -s'
gsw='git switch'
gswc='git switch -c'
..=cd ..
-='cd -'
Installing
- Install zsh and change default shell
sudo apt install zsh && chsh --shell /bin/zsh
- Install oh-my-zsh
sh -c "$(curl -fsSL https://raw.github.com/ohmyzsh/ohmyzsh/master/tools/install.sh)"
The Best Zsh Plugins
These four plugins help you reuse your commands and find mistakes while
typing. They make your shell be a little more like fish shell. By the way, I
tried fish before, but it is not POSIX compatible and copying commands from
others started to be a pain, as I always had to do some minor editing for
things like VAR=2 run_command
.
I think the most striking command of the 4 is history-search-multi-word
. It
improves the Ctrl + R
shortcut, giving you fuzzy search over your history!
Thank me later.
To install them, we are going to use a plugin manager called zinit.
sh -c "$(curl -fsSL https://raw.githubusercontent.com/zdharma/zinit/master/doc/install.sh)"
echo 'zinit load "zdharma/history-search-multi-word"' >> ~/.zshrc
echo 'zinit load "zsh-users/zsh-history-substring-search"' >> ~/.zshrc
echo 'zinit load "zsh-users/zsh-autosuggestions"' >> ~/.zshrc
echo 'zinit load "zsh-users/zsh-syntax-highlighting"' >> ~/.zshrc
Other Zsh Plugins
I don't consider the plugins below essential, but they are nice.
colorize
Colorize allows you to cat files with syntax highlighting. You can install it via:
echo 'export GOPATH=$(go env GOPATH)' >> ~/.zshrc
echo 'export PATH=$GOPATH/bin:"$PATH"' >> ~/.zshrc
echo 'export ZSH_COLORIZE_TOOL=chroma' >> ~/.zshrc
sudo add-apt-repository ppa:longsleep/golang-backports
sudo apt update
sudo apt install golang-go
source ~/.zshrc
go get -u github.com/alecthomas/chroma/cmd/chroma
After the above, you should add colorize
to the plugins
variable in ~/.zshrc
.
Colorize supports syntax-highlighting via pygments and chroma. Chroma has less features, but is written in go and seems faster than pygments, so I use it.
To test colorize, you can try ccat
(color cat?) with any code file you
have, or you could do:
echo '#include<stdio.h>\nint main() {\n printf("Hello World"\n);\n}' > test.c
ccat test.c
colored-man-pages
The name says it all: colors in man pages.
To install it: add colored-man-pages
to the plugins
variable in ~/.zshrc
.
To test it: man less
or any other man-page. You should see some colors.
copyfile
Allows you to copy a file to the clipboard from the terminal.
To install it: add copyfile
to the plugins
variable in ~/.zshrc
.
To test it: copyfile test.c
and then try to paste is somewhere.
gitignore
You can search for gitignore files for certain languages from your terminal and add them to your project.
To install it: add gitignore
to the plugins
variable in ~/.zshrc
.
To test it: gi list
to see all keywords. gi swift > swift.gitignore
to see
an example file.
Default EDITOR
Every time I install an OS from scratch and type git commit
, I see the
EDITOR
defined in this variable pop up. Sometimes, the default is nano
,
which I dislike. I usually leave vim
as the default, but you can set
whatever.
The dotfile from Oh-my-zsh has some commented lines setting up that variable, just make sure to uncomment them and set to your favorite editor:
if [[ -n $SSH_CONNECTION ]]; then
export EDITOR='vim'
else
export EDITOR='mvim'
fi
I usually change mvim
by vim
as well.
Fancy (and fast) command line tools
GNU Tools?
Imagine the gnu tools find
, ls
and grep
. Now, imagine they are all faster
and have sensible defaults for git repositories (like not searching ignored
files). These tools are:
All the tools above are written in rust. They are all available in homebrew for
macOS, but not in the default ubuntu repos. I ended up installing them on Linux
using cargo
, which requires you to install rust. If you are fine with that,
follow the instructions below:
# Install rust via rustup
# More info in https://www.rust-lang.org/tools/install
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
# Install command line tools
cargo install exa fd-find ripgrep
Fuzzy File Finding
FZF allows you to find files, like find
and fd
, but you can do fuzzy
searches and it shows you the list of candidates while you type. There is also
a plugin for vim
, which is super helpful and is the way I use this plugin the
most. For more info, including about the vim plugin, check the README on git.
To install it:
git clone --depth 1 https://github.com/junegunn/fzf.git ~/.fzf
~/.fzf/install
Spacemacs
There is much to love in emacs. However, customizing it is quite an ordeal. I prefer to have an editor with sensible defaults and then I just tweak a few details. Spacemacs allows me to have just that for emacs, which is awesome.
To install it: get emacs 26 and then clone the develop spacemacs repo. I recommend the develop branch because the community keeps adding incredible stuff in that branch that will take a very long time to get to master.
sudo add-apt-repository ppa:kelleyk/emacs
sudo apt update
sudo apt install emacs26
git clone -b develop https://github.com/syl20bnr/spacemacs ~/.emacs.d
There is much to learn about this one. Check the docs for more info. Some shortcuts I like:
SPC p p
- pick a project and find files in it; any git repo you accessed before with emacs is automatically added to the repo list
SPC b b
- open recent buffer; even if you closed files, you can easily open them if you remember part of the name
There are also several shortcuts for org-mode
and other modes.
File Conversion
I created a few aliases that help me with file conversions that I do frequently, namely:
- markdown2org
- markdown2html
- mov2mkv
If you want them:
curl -fsSL https://gist.githubusercontent.com/ataias/9dfac5c50f71b8207c9abcab265d41a7/raw/98fe0cc665deb3860b613c7ab57df2953c2bd702/conversion-aliases.zsh > ~/.conversion-aliases.zsh
echo 'source ~/.conversion-aliases.zsh' >> ~/.zshrc
Conclusion
We learned how to set up the basic shell given to us in a Unix machine. When
third party packages were necessary, we used apt
or a plugin manager for
them. The instructions are easily convertible to macOS using the homebrew
package manager. The final ~/.zshrc
file is in this gist.
I hope you enjoyed this post. I appreciate any constructive feedback and I would love to hear any tweaks you made to this configuration, or tell me more about your own.