Setup practical and appealing terminal on macOS
Tags: iterm, macos, fish, beginners
Published: 2023-04-12 15:54:18

*Originally published at [author's own blog](https://www.fivesssss.io/terminal-setup-macos)*

## How to set up an appealing and practical terminal on macOS

### Disclaimer - Default terminal

![macOS Default Terminal](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/kt73m808zjvunaygv1zf.png)

Now I get it, default terminal is not that bad, it is usable enough and could get you far. Personally I have used various terminal applications and various [shells](https://unix.stackexchange.com/questions/4126/what-is-the-exact-difference-between-a-terminal-a-shell-a-tty-and-a-con) mainly due to my curiosity.

> Curiosity is an interesting feeling... but also dangerous

I am not going to tell you that you need to change anything with the current setup that you have, if it does the job for you that's good, and I support that, customizing your environment too much could hurt your productivity, however, if you have a bit of a free time and curious to try out something else, I have more or less optimal configuration that worked for me and I certainly hope it would work for you.

The article focuses on essentials to prevent being overwhelmed by all options and configurations. If you do not care about the looks too much you can straight jump to [practicality](#practicality-fish-shell-and-utilities) part, although I would recommend skimming through the whole article, I promise it won't take long.

Also, I will be using [homebrew](https://brew.sh/) to install all the needed applications, you can use any other way.

### Looks - Terminal app and prompt

- iTerm2
- Starship Prompt

#### iTerm2

The main reason of why I use iTerm2 is that I am used to it, you do not have to use iTerm2 to achieve the same look, stay tuned I am in the middle of reviewing other alternatives. For now, let's use iTerm2. Additionally, if you ever decide to extend configuration, it is much easier to do that in iTerm2 with all the customization options you have.

Let's start by installing iTerm2:

```bash
$ brew install --cask iterm2
```

Once installed, we will customize following:

- Colors
- Fonts
- Window opacity

##### Colors

In order to update the colors all is needed is the color scheme defined as `.itermcolors` file, for example, the theme I currently use is ["Tokyonight"](https://github.com/folke/tokyonight.nvim). To acquire iTerm2 theme we need to find relevant file together with theme. Most of the theme providers, be it editor theme, shell theme or something else have `.itermcolors` provided together too. For example you could find "Tokyonight" iTerm2 color scheme [here](https://github.com/folke/tokyonight.nvim/tree/main/extras/iterm). Once you find the file, open it in raw view and copy the content. Create a local file with `.itermcolors` extension and paste the copied content into it.

> Or you can just download those files, your choice

These are some themes I have, [poimandres](https://github.com/rumaan/poimandres-iterm/tree/main/themes),[kanagawa](https://github.com/rebelot/kanagawa.nvim/blob/master/extras/kanagawa.itermcolors), [tokyonight](https://github.com/folke/tokyonight.nvim/tree/main/extras/iterm)

![itermcolors](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/yoj4sqo0jqokl7dqs4i0.png)

Once you have files on your system, open up iTerm2, open Settings in the menu bar and go to Profiles > Colors. You should be able to see Color Presets menu in the bottom-right corner, select the menu and choose Import, where you can choose the `.itermcolors` file that you have created.

![iterm-color-presets](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/pqbgna04d19319bj3vqa.png)

Also, you can browser more themes [here](https://iterm2colorschemes.com/)

##### Fonts (Nerd Fonts)

Nerd fonts are necessary in order to render certain glyphs (icons). Nerd font is just a patched version of a normal font to enable ability to have icons rendered correctly. I am not going to explain on how to install fonts in macOS, however my preferred method is using `brew`, personal I use [Victor Mono font](https://rubjo.github.io/victor-mono/), you could install it via brew like so:

```bash
$ brew install --cask font-victor-mono-nerd-font
```

I use following [repository](https://github.com/Homebrew/homebrew-cask-fonts) as a source to install fonts and review which nerd fonts are available, you can browse [casks folder](https://github.com/Homebrew/homebrew-cask-fonts/tree/master/Casks) there to find available fonts. Once nerd font is installed head over to the Settings > Profile > Text menu of iTerm2. You can choose your desired font in the "Font" selection.

![iterm-fonts](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/2pmoy8avdi7zwfkquqwp.png)

##### Window opacity

> This might not be usable for you depending on your theme and workflow, do not ruin your eyes for the looks only, experiment and find what works for you

Window opacity would add transparency to the terminal, while not very practical I personally find very aesthetically pleasing. Open Settings > Profiles > Window. You will be able to adjust transparency there, add some blur for better visibility.

![iterm-transparency](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/usf8ifkvoaa6nw0jhuoo.png)

#### Starship

[Starship](https://starship.rs/) is a "blazingly fast" cross shell prompt. It has many features and reasons to use, but I use it primarily for easiness of configuration and because it is written in rust (I am considering switching my terminal soon due to that, don't judge me).

Use following command to install:

```bash
$ brew install starship
```

Once installed ensure your shell is configured to auto-start starship prompt, checkout [here](https://starship.rs/guide/#%F0%9F%9A%80-installation) for more details. For fish shell, which is what we are going to setup in [Practicality](#practicality-fish-shell-and-utilities) section insert following in your `~/.config/fish/config.fish`:

```bash
starship init fish | source
```

Once we have starship shell up and running, let's modify the configuration, I am not going to teach you how to configure prompt, you could read more [here](https://starship.rs/config/#prompt), however to save you time here is the configuration that I use, it should be enough to get you started:

```toml
# ~/.config/starship.toml

[battery]
full_symbol = "🔋"
charging_symbol = "🔌"
discharging_symbol = "⚡"

[[battery.display]]
threshold = 30
style = "bold red"

[character]
error_symbol = "[✖](bold red) "

[cmd_duration]
min_time = 10_000  # Show command duration over 10,000 milliseconds (=10 sec)
format = " took [$duration]($style)"

[directory]
truncation_length = 5
format = "[$path]($style)[$lock_symbol]($lock_style) "

[git_branch]
format = " [$symbol$branch]($style) "
symbol = "🍣 "
style = "bold yellow"

[git_commit]
commit_hash_length = 8
style = "bold white"

[git_state]
format = '[\($state( $progress_current of $progress_total)\)]($style) '

[git_status]
conflicted = "⚔️ "
ahead = "🏎️ 💨 ×${count}"
behind = "🐢 ×${count}"
diverged = "🔱 🏎️ 💨 ×${ahead_count} 🐢 ×${behind_count}"
untracked = "🛤️  ×${count}"
stashed = "📦 "
modified = "📝 ×${count}"
staged = "🗃️  ×${count}"
renamed = "📛 ×${count}"
deleted = "🗑️  ×${count}"
style = "bright-white"
format = "$all_status$ahead_behind"

[hostname]
ssh_only = false
format = "<[$hostname]($style)>"
trim_at = "-"
style = "bold dimmed white"
disabled = true

[memory_usage]
format = "$symbol[${ram}( | ${swap})]($style) "
threshold = 70
style = "bold dimmed white"
disabled = false

[package]
disabled = true

[python]
format = '[${symbol}${pyenv_prefix}(${version} )(\($virtualenv\) )]($style)'
style = "bold green"

[rust]
format = "[$symbol$version]($style) "
style = "bold green"

[time]
time_format = "%T"
format = "🕙 $time($style) "
style = "bright-white"
disabled = false

[username]
style_user = "bold dimmed blue"
show_always = false

[nodejs]
format = "via [🤖 $version](bold green) "
```

### Practicality - Fish Shell and utilities

#### Fish Shell - Best shell for me

Fish shell feels fast with out of the box autocomplete support based on your history. I started to use fish long time and just stuck with it, recently I have tried zsh shell with powerlevel10k setup, felt slower so I went back to fish.

To install:

```bash
$ brew install fish
```

To set fish as your default shell:

```bash
$ fish
$ fish_add_path /opt/homebrew/bin
$ echo "/opt/homebrew/bin/fish" | sudo tee -a /etc/shells
$ chsh -s /opt/homebrew/bin/fish
```

- `fish_add_path /opt/homebrew/bin` ensures fish recognizes homebrew `$PATH`, we would need to add that into our config later
- `echo "/opt/homebrew/bin/fish" | sudo tee -a /etc/shells` adds fish shell to known shells
- `chsh -s /opt/homebrew/bin/fish` sets fish as your default shell

Once fish shell installed and configured as your default shell, you would need to logout and log back in, now whenever you open iTerm2 it would start with fish shell.

Let's edit the configuration.

- Navigate to your fish config folder `$ cd ~/.config/fish`
- Open `config.fish` file with your favourite code/text editor
- Add the line that we have already covered there `fish_add_path /opt/homebrew/bin`
- Also add the `starship` init script `starship init fish | source`, note that it should be **always at the end of the file**

Save the file, close iTerm2 and open it again, now you should see a nice looking terminal.

#### exa - A modern ls replacement

exa is a faster and modern replacement for ls (written in rust btw).

Install it like so:

```bash
$ brew install exa
```

If you don't want to combat your muscle memory add these aliases to your `config.fish` file:

```bash
alias ls='exa -al --color=always --group-directories-first --icons' # preferred listing
alias la='exa -a --color=always --group-directories-first --icons' # all files and dirs
alias ll='exa -l --color=always --group-directories-first --icons' # long format
alias lt='exa -aT --color=always --group-directories-first --icons' # tree listing
alias l.="exa -a | egrep '^\.'" # show only dotfiles
```

#### ripgrep - Faster grep (Optional)

ripgrep is a faster `grep` (written in rust btw).

Install it like so:

```bash
$ brew install ripgrep
```

Add this alias to your `config.fish`:

```bash
alias grep='rg --color=auto'
```

Example usage:

```bash
$ grep <keyword to get> <path to file>
```

For example to get alias keyword in `config.fish` file use following:

```bash
$ grep alias .config/fish/config.fish
```

See [docs](https://github.com/ogham/exa) for more.

#### fd - Faster find (Optional)

fd is fast and user friendly alternative to `find` (written in rust btw).

Install it like so:

```bash
$ brew install fd
```

Example usage:

```bash
$ fd config.fish
```

See [docs](https://github.com/sharkdp/fd) for more.

#### Bonus configurations for fish shell

Aliases (pretty self-explanatory):

```bash
alias ..='cd ..'
alias ...='cd ../..'
alias ....='cd ../../..'
alias .....='cd ../../../..'
alias ......='cd ../../../../..'
alias dir='dir --color=auto'
alias please='sudo'
```

If you notice everytime you open terminal it shows a "greeting" message from fish, to remove add this in your `config.fish`:

```bash
set fish_greeting ""
```