Configuring Your Shell Environment
Tags: shell, config, setup
Published: 2022-10-18 16:39:31

---
title: Configuring Your Shell Environment
published: true
description: 
tags: [shell, config, setup]
---

# My Shell Config

For my shell config I use a combination of tools, namely:

- [zsh](https://www.zsh.org/) :(as my shell)
- [oh-my-zsh](https://github.com/ohmyzsh/ohmyzsh/wiki) :(as my framework for configuring my shell)
- [starship](https://starship.rs/) :(as my theme for my shell)
- [iterm2](https://www.iterm2.com/) :(as my terminal for interacting with my shell)

(optional extras)
- [broot](https://github.com/Canop/broot#broot) :(as a plugin for navigating my fs like finder within my shell)
- [fzf](https://github.com/junegunn/fzf#-) :(a fuzzy search tool, think grep but interactive)
- [cfg](https://www.atlassian.com/git/tutorials/dotfiles) :(a special git setup for tracking changes to your config files)
- [quick-look-plugins](https://github.com/sindresorhus/quick-look-plugins#quick-look-plugins-) :(these let you peek into files like .js or .json using mac's quicklook feature (spacebar))

And some zsh plugins I use: (the more `*` next to the name the higher I recommend it)

- [aws](https://github.com/ohmyzsh/ohmyzsh/blob/master/plugins/aws/README.md#aws)* :(sets up `awscli` auto complete + adds super handy profile commands)
- [alias-tips](https://github.com/djui/alias-tips#alias-tips)** :(let's you know when you type the long form of an alias you have)
- [autojump](https://github.com/wting/autojump#name)* :(use j to jump to directories containing terms. Directories must be visited first before they can be jumped to.)
- [autoupdate](https://github.com/TamCore/autoupdate-oh-my-zsh-plugins#autoupdate-zsh-plugin)* :(automatically updates custom plugins)
- [common-aliases](https://github.com/ohmyzsh/ohmyzsh/blob/master/plugins/common-aliases/common-aliases.plugin.zsh) :(add tons of aliases like `la`, `ll` etc)
- [git-auto-fetch](https://github.com/ohmyzsh/ohmyzsh/tree/master/plugins/git-auto-fetch)* :(automatically "fetches" for new changes of directory you're in)
- [git-extras](https://github.com/ohmyzsh/ohmyzsh/tree/master/plugins/git-extras) :(adds a bunch of helpful git aliases and extra commands)
- [gitfast](https://github.com/ohmyzsh/ohmyzsh/tree/master/plugins/gitfast) :(adds git tab completion)
- [git-flow](https://github.com/ohmyzsh/ohmyzsh/tree/master/plugins/git-flow) :(adds completion for git flow commands)
- [node](https://github.com/ohmyzsh/ohmyzsh/tree/master/plugins/node) :(adds completion for node)
- [npm](https://github.com/ohmyzsh/ohmyzsh/tree/master/plugins/npm)* :(adds completion for npm)
- [zsh-autosuggestions](https://github.com/zsh-users/zsh-autosuggestions#zsh-autosuggestions)** :(adds suggestions as you type)
- [zsh-interactive-cd](https://github.com/ohmyzsh/ohmyzsh/tree/master/plugins/zsh-interactive-cd)* :(cd + tab to fuzzy search navigate)
- [zsh_reload](https://github.com/ohmyzsh/ohmyzsh/tree/master/plugins/zsh-reload)* :(adds `src` command for better full compile reload)

A full list of `oh-my-zsh` plugins can be found [here](https://github.com/ohmyzsh/ohmyzsh/wiki/Plugins)
Another handy list of plugins can be found [here](https://github.com/unixorn/awesome-zsh-plugins#plugins)

## Installation

There are a few steps to install all this, but nothing too crazy it should be less than 5min if you're on a decent internet connection.
And once installed and setup, you'll be flying at the helm of your terminal provided with tools to help you get faster along the way (alla `alias-tips` and `zsh-autosuggestions`)

### Install Oh My ZSH

For getting started, let's install oh-my-zsh

This script will install the `oh-my-zsh` framework if it's not already installed

```bash
# Install On-My-Zsh
if [ ! -d $HOME/.oh-my-zsh ]; then
    sh -c "$(curl https://raw.githubusercontent.com/robbyrussell/oh-my-zsh/master/tools/install.sh)" --unattended
else
    echo "Oh-My-Zsh already installed."
fi
```

If everytime when you start a shell and see a big annoying warning about insecure directories, simply run this to fix it:

`compaudit | xargs sudo chmod g-w` (may require sudo, [see why here](https://github.com/zsh-users/zsh-completions/issues/433#issuecomment-815872839))


### Install additional plugins

By default `oh-my-zsh` comes preloaded with a ton of built in plugins that you can load by adding them to your `~/.zshrc` file. However some of my favorites aren't in that list.
This section describes how to install extra plugins, namely `alias-tips autojump autoupdate autosuggestions`

In order to install an additional plugin for `zsh` all you have to do is install the git repo of the plugin to your `$ZSH_CUSTOM/plugins` directory, then add the folder name to your `plugins` list in your `~/.zshrc` file.

For convenience, I've created a script below that should install the ones I'm recommending.

```bash
# Set ZSH_CUSTOM if it's not already (used by our PLUGINS_PATH below)
if [ -z $ZSH_CUSTOM ]; then
    ZSH_CUSTOM="$HOME/.oh-my-zsh/custom"
fi

# Install additional plugins to this path
PLUGINS_PATH="${ZSH_CUSTOM}/plugins"

# Define function for installing plugins for use below
function install-plugin() {
    plugin_repo=$1
    plugin_name=$2

    echo "Downloading Plugin: $plugin_name"
    echo "Using: $plugin_repo"
    echo "To: $PLUGINS_PATH/$plugin_name"
    echo "git clone $plugin_repo $PLUGINS_PATH/$plugin_name"
    git clone $plugin_repo $PLUGINS_PATH/$plugin_name
    plugin_list="${plugin_list}$plugin_name "
}

echo "Installing Plugins..."
install-plugin https://github.com/djui/alias-tips alias-tips
install-plugin https://github.com/wting/autojump autojump
install-plugin https://github.com/TamCore/autoupdate-oh-my-zsh-plugins autoupdate
install-plugin https://github.com/zsh-users/zsh-autosuggestions autosuggestions

echo "Plugins Installed. Add them by copying th following into your ~/.zshrc
    plugins=( $plugin_list )
"

# For auto jump we must install it using it's own script
cd "$PLUGINS_PATH/autojump"
./install.py
```
Okay this may be a bit much at first, so let's break it down:

1. First we're setting up an env var called `ZSH_CUSTOM` if it's not already set. We use this to determine where the plugins should be installed to. If you have a special location you want, you can use that, otherwise we'll expect it to be in the `.oh-my-zsh` directory.
2. Then we set the `PLUGINS_PATH` directory, which again just tells us where to install the plugins.
3. Next we setup the `install-plugin` function that just takes a git repo (`plugin_repo`) and a name (`plugin_name`), then downloads the plugin repo to our `PLUGINS_PATH` location and names it `plugin_name`. It outputs the plugins as an array you can copy paste into your `.zshrc` later if needed (we don't).
4. Then we actually install the plugins `alias-tips`, `autojump`, `autoupdate` and `autosuggestions`. These are all plugins that aren't shipped with the `oh-my-zsh` framework but are freaking sweet!
5. For our final step we `cd` into the autojump repo and run it's special installer to finish off it's install. (I'm actually unsure if we need to be in it's directory when running, so let me know in the comments!)

And that's it! The plugins are installed.

### Install the Starship theme

The starship theme is a super fast theme for `zsh` that gives you handy color-coded context in your prompt based on your current user/dir.  It's written in rust, so it's secure and blazing fast for super quick start up times.

Just run this line to install it:
`curl -fsSL https://starship.rs/install.sh | bash`

I love this theme, because it's pre-configured out of the box with great defaults, but is also really easy to customize further.
It does wonderful things like tell you if you have git changes, what version node, docker and ruby packages are. And if you use aws, gcp or azure it nows the context of your profiles/config, super handy when switching around a bunch.

### Install additional tools

These tools are super helpful and require `brew` to install (there are other ways, but brew is the easiest)

(note: you can combine the installs into one command for an all in one install)

```bash
# zsh-syntax-highlighting leaving for last in case brew isn't installed
brew install zsh-syntax-highlighting

# Super awesome dir navigation tool
brew install broot

# Super awesome fuzzy search tool/pipe
brew install fzf

# This font is needed by the starship theme to display ligatures/icons, but first we need to tell brew where to find it
brew tap homebrew/cask-fonts
brew cask install font-fira-code

# ql are quicklook plugins on mac that allow you to quickly view .json, markdown and other files without having to open them
brew cask install qlcolorcode qlstephen qlmarkdown quicklook-json qlimagesize quicklookase qlvideo
```

And if you want it all in one line:

```bash
brew install zsh-syntax-highlighting broot fzf && brew tap homebrew/cask-fonts && brew cask install font-fira-code qlcolorcode qlstephen qlmarkdown quicklook-json qlimagesize quicklookase qlvideo
```

**NOTE**: I actually don't use `fzf` or `broot` nearly as often as I used to. `broot` has primarily been replaced for me with `autojump` + `zsh-interactive-cd` and I only use `fzf` when I'm searching through logs.

### Configue .zshrc

Now that everything is installed, the only thing left to do is configure your `.zshrc` file. Copy this and overwrite your `~/.zshrc` file. (keep your aliases if you have any, I recommend create a `.zshrc.backup` file for your old `.zshrc` before copying, then bring over your aliases as needed.)

```zsh
# If you come from bash you might have to change your $PATH.
# export PATH=$HOME/bin:/usr/local/bin:$PATH

# Path to your oh-my-zsh installation.
export ZSH="$HOME/.oh-my-zsh"
export ZSH_CUSTOM="$HOME/.oh-my-zsh/custom"

# Set name of the theme to load --- if set to "random", it will
# load a random theme each time oh-my-zsh is loaded, in which case,
# to know which specific one was loaded, run: echo $RANDOM_THEME
# See https://github.com/robbyrussell/oh-my-zsh/wiki/Themes
# ZSH_THEME="spaceship" # I'm using starhip (see below, where it's configured)

# Set list of themes to pick from when loading at random
# Setting this variable when ZSH_THEME=random will cause zsh to load
# a theme from this variable instead of looking in ~/.oh-my-zsh/themes/
# If set to an empty array, this variable will have no effect.
# ZSH_THEME_RANDOM_CANDIDATES=( "robbyrussell" "agnoster" )

# Uncomment the following line to use case-sensitive completion.
# CASE_SENSITIVE="true"

# Uncomment the following line to use hyphen-insensitive completion.
# Case-sensitive completion must be off. _ and - will be interchangeable.
HYPHEN_INSENSITIVE="true"

# Uncomment the following line to disable bi-weekly auto-update checks.
# DISABLE_AUTO_UPDATE="true"

# Uncomment the following line to automatically update without prompting.
# DISABLE_UPDATE_PROMPT="true"

# Uncomment the following line to change how often to auto-update (in days).
export UPDATE_ZSH_DAYS=8

# Uncomment the following line if pasting URLs and other text is messed up.
# DISABLE_MAGIC_FUNCTIONS=true

# Uncomment the following line to disable colors in ls.
# DISABLE_LS_COLORS="true"

# Uncomment the following line to disable auto-setting terminal title.
# DISABLE_AUTO_TITLE="true"

# Uncomment the following line to enable command auto-correction.
ENABLE_CORRECTION="true"

# Uncomment the following line to display red dots whilst waiting for completion.
COMPLETION_WAITING_DOTS="true"

# Uncomment the following line if you want to disable marking untracked files
# under VCS as dirty. This makes repository status check for large repositories
# much, much faster.
# DISABLE_UNTRACKED_FILES_DIRTY="true"

# Uncomment the following line if you want to change the command execution time
# stamp shown in the history command output.
# You can set one of the optional three formats:
# "mm/dd/yyyy"|"dd.mm.yyyy"|"yyyy-mm-dd"
# or set a custom format using the strftime function format specifications,
# see 'man strftime' for details.
HIST_STAMPS="mm/dd/yyyy"

# Would you like to use another custom folder than $ZSH/custom?
# ZSH_CUSTOM=/path/to/new-custom-folder

# Which plugins would you like to load?
# Standard plugins can be found in ~/.oh-my-zsh/plugins/*
# Custom plugins may be added to ~/.oh-my-zsh/custom/plugins/
# Example format: plugins=(rails git textmate ruby lighthouse)
# Add wisely, as too many plugins slow down shell startup.
plugins=(
    aws # sets up `awscli` tab completion + profile changing commands
    alias-tips # let's you know when you have an alias you can use
    autojump # use j to jump to directories containing terms. Directories must be visited first before they can be jumped to.
    autoupdate # automatically updates custom plugins
    common-aliases # add tons of aliases like la ll etc
    git-auto-fetch # automatically "fetches" for new changes of directory you're in
    git-extras # adds a bunch of helpful git aliases and extra commands
    gitfast # adds git tab completion
    git-flow # adds completion for git flow commands
    node # adds completion for node
    npm # adds completion/aliases for npm
    zsh-autosuggestions # adds suggestions as you type
    zsh-interactive-cd # cd + tab to fuzzy search navigate
    zsh_reload # adds `src` command for better full compile reload
)

# Load Oh My ZSH
source $ZSH/oh-my-zsh.sh

# autojump config
[[ -s $HOME/.autojump/etc/profile.d/autojump.sh ]] && source $HOME/.autojump/etc/profile.d/autojump.sh

autoload -U compinit && compinit -u

# FZF config
export FZF_BASE=~/.fzf
export PATH="/usr/local/sbin:$PATH"
[ -f ~/.fzf.zsh ] && source ~/.fzf.zsh

# zsh-syntax-highlighting
source /usr/local/share/zsh-syntax-highlighting/zsh-syntax-highlighting.zsh

# broot
source $HOME/.config/broot/launcher/bash/br


# User configuration

export MANPATH="/usr/local/man:$MANPATH"

# You may need to manually set your language environment
# export LANG=en_US.UTF-8

# Preferred editor for local and remote sessions
if [[ -n $SSH_CONNECTION ]]; then
  export EDITOR='code'
else
  export EDITOR='code'
fi

# Compilation flags
# export ARCHFLAGS="-arch x86_64"

# Set personal aliases, overriding those provided by oh-my-zsh libs,
# plugins, and themes. Aliases can be placed here, though oh-my-zsh
# users are encouraged to define aliases within the ZSH_CUSTOM folder.
# For a full list of active aliases, run `alias`.
#
# Example aliases
alias zshconfig="code ~/.zshrc"
alias ohmyzsh="code ~/.oh-my-zsh"
alias reload="source ~/.zshrc"

# My Custom Aliases change 
alias please="sudo !!"
alias tmp="cd ~/Development/tmp"
alias proj="cd ~/Projects"
alias work="cd ~/Work"
alias co.="code ."

### CFG  Setup
# Alias for the main cfg git
# alias cfg='/usr/bin/git --git-dir=$HOME/.cfg/ --work-tree=$HOME'
# export function cfg {
#    /usr/bin/git --git-dir=$HOME/.cfg/ --work-tree=$HOME $@
# }


# lastly init starship theme
eval "$(starship init zsh)"

```

### (Optional) Setup iterm2

Install iterm2 using brew or the link I provided above. 

#### Setup Font For Starship

Then go to `Preferences > Profiles > Text > Non-ASCII Font` and select `Fira Code` as your font, this will make iterm display special icons that are used by `starship` theme. Also be sure to select the `use ligatures` option for extra sweet `->`.

#### Setup Natural Text Editing

Go to `Preferences > Profiles > Keys` The select the `Presets...` dropdown to bring up a list of presets. Select the `Natural Text Editing` preset to add it to your profile.
The `Natural Text Editing` preset gives you a more natural navigation and editing experience in the terminal. You can use things `cmd+delete` to delete a whole line, `option+<-` to move one word over at a time. This is more akin to other text editing environments on your computer.

See this [SO](https://stackoverflow.com/a/22312856) for more info on it.

### (Optional) Setup .cfg git directory

I use a special git directory I named `.cfg` to track and manage my config files. It's amazing for making changes/updates and being able to maintain those over time and across computers.

I won't go into all the details, but only list out the steps to get it configure. Follow this [blog](https://www.atlassian.com/git/tutorials/dotfiles) for the details.

1. Setup the repo in your root dir

```bash
git init --bare $HOME/.cfg
alias cfg='/usr/bin/git --git-dir=$HOME/.cfg/ --work-tree=$HOME'
cfg config --local status.showUntrackedFiles no
echo "alias cfg='/usr/bin/git --git-dir=$HOME/.cfg/ --work-tree=$HOME'" >> $HOME/.bashrc
```

(if you copied my `.zshrc` you don't need the last line, just uncomment the `cfg` aliases at the bottom, reload your zsh and you're good to go)

2. Test it out by adding a few files to track

```bash
cfg status
cfg add .zshrc
cfg commit -m "Add inital .zshrc config"
cfg add .bashrc
cfg commit -m "Add bashrc"
cfg remote add origin <insert repo url here>
cfg push origin master
```

## The End!

And that's it! That's how to configure a super awesome, fast and powerful shell in less than 15min!

Get started by playing around with these commands:

- `$ br` > opens `broot` so you can navigate directories and run commands in them quickly without all the `cd + ls` looping mess

- `$ fzf` > will immediately start searching your filesystem, with an interactive search, so you can type characters and it will search for you. This even works with `|` so you can interactively search `logs`, `history`, `files` anything!

- Try typing out some common `git` commands and get `alias-tips` to suggest faster alternatives.

- You should also start seeing an auto suggest when you start typing familiar commands from your `history`

There's a lot more, but hopefully this gets you running in the right direction to explore and feel powerful. Enjoy!