Configuring Your macOS Prompt is an essential step in setting up your command line interface (CLI) to suit your preferences and maximize your productivity. In macOS, the prompt is the text that appears before you type a command in the CLI, and it can provide valuable information such as the current user, the host name, the current working directory, and more.

By customizing your prompt, you can tailor the information displayed to your needs, making it easier to navigate and work with your files and folders. In this blog post, we’ll take a closer look at configuring your macOS prompt, including how to customize its appearance and integrate Git branch information into it. Additionally, we’ll explore how to use LSCOLORS to customize the colors of your file listings, providing a complete guide to optimizing your CLI for your workflow.

In my setup, I use Pyenv to manage multiple versions of Python. It allows me to easily install, uninstall, and switch between different versions of Python. Pyenv also has a virtualenv plugin, which allows me to create and manage isolated Python environments for different projects. This can help avoid conflicts between packages installed in different projects. In case you want to read more about Pyenv, its uses and how to install, check this post.

Configuring ‘.zshrc’ file

In macOS and other Unix-based operating systems, the .zshrc file is a configuration file for the Zsh shell, which is a popular alternative to the default Bash shell. When you open a terminal window, the Zsh shell reads the .zshrc file and executes any commands or settings contained within it. This file allows you to customize various aspects of your terminal environment, including setting environment variables, defining aliases, configuring the prompt, and more. By editing the .zshrc file, you can configure your terminal environment to suit your preferences and workflow.

To locate and edit the .zshrc file, you can navigate to your home directory using the terminal and use a text editor to modify it. We can open and edit it using any text editor. I will use nano.

Navigate to your home directory and open the .zshrc and paste in the script below:

# open the file, edit and save!
sudo nano .zshrc

And paste in the script below:

# Initialize pyenv
if command -v pyenv 1>/dev/null 2>&1; then
  eval "$(pyenv init -)"
fi

# Add custom, local installations to PATH
PATH=/usr/bin:/bin:/usr/sbin:/sbin:/usr/local/bin:/usr/local/sbin:"$PATH"
export PYENV_ROOT="$HOME/.pyenv"
export PATH="$PYENV_ROOT/bin:$PATH"
eval "$(pyenv init --path)"

# Pyenv virtualenv plugin automatic setup
eval "$(pyenv virtualenv-init -)"

# Git Integration

autoload -Uz vcs_info
precmd_vcs_info() { vcs_info }
precmd_functions+=( precmd_vcs_info )
setopt prompt_subst
zstyle ':vcs_info:git:*' formats '(%b)'
zstyle ':vcs_info:*' enable git
zstyle ':vcs_info:*' check-for-changes true

# Prompt (aka PS1)
PROMPT="%B%F{014}%n%f%b %F{015}in%f %B%F{011}%2~%f%b \$vcs_info_msg_0_ $ "


# Colors for ls
export CLICOLOR=1
export LSCOLORS=GxFxCxDxBxegedabagaced

That was a bit nasty, let’s break it down…

Initialise Pyenv

This code initializes Pyenv and sets up the shell to use it. We will also add custom and local installations to the system’s PATH variable so that the system can find executables installed in those locations. It also sets up the PYENV_ROOT and PATH variables so that the shell knows where to find the Pyenv executable and other dependencies.

# Initialize pyenv
if command -v pyenv 1>/dev/null 2>&1; then
  eval "$(pyenv init -)"
fi

# Add custom, local installations to PATH
PATH=/usr/local/bin:/usr/local/sbin:"$PATH"
export PYENV_ROOT="$HOME/.pyenv"
export PATH="$PYENV_ROOT/bin:$PATH"
eval "$(pyenv init --path)"

Next, we’ll sets up the pyenv-virtualenv plugin, which provides additional functionality for creating and managing virtual environments in Python.

# Pyenv virtualenv plugin automatic setup
eval "$(pyenv virtualenv-init -)"

Configuring Git branch information

This section integrates Git branch information into the prompt. Vcs_info is a shell function that is available in the Zsh shell and is used to display information about the current version control system in use (e.g., Git) in the prompt. It can display information such as the name of the current branch, the commit hash, and whether there are any uncommitted changes.

# Git Integration
autoload -Uz vcs_info
precmd_vcs_info() { vcs_info }
precmd_functions+=( precmd_vcs_info )
setopt prompt_subst
#RPROMPT=\$vcs_info_msg_0_
zstyle ':vcs_info:git:*' formats '(%b)'
zstyle ':vcs_info:*' enable git
zstyle ':vcs_info:*' check-for-changes true

autoload loads the vcs_info function, which retrieves Git branch information.

  • The "-U" option tells Zsh to unload the function before loading it. This is useful when reloading a function definition that has changed since it was last loaded.
  • The "-z" option tells Zsh to create a function that is “zeroed” (i.e., set to null) until it is actually called. This can save memory by not allocating memory for the function until it is needed.

Next, precmd_vcs_info function is called before each prompt is displayed and updates the Git branch information.

  • precmd_functions variable is an array that contains all functions to be called before the prompt is displayed.
  • setopt prompt_subst command enables parameter expansion in the prompt, which is necessary for Git branch information to be displayed.

The zstyle commands configure the appearance of the Git branch information.

  • :vcs_info:git:* format string applies to Git repositories and specifies that the branch name should be wrapped in parentheses.
  • :vcs_info:* line specifies that Git should be enabled for all repositories.
  • check-for-changes option specifies that Git should check for uncommitted changes before displaying the branch information.

In the context of the zstyle command, %b is a format specifier that stands for “branch name”. So if the current Git branch is named main, the prompt will display (main).

The formats style can be customized further using other format specifiers, such as %r for the remote repository name, %m for the merge status, %u for the number of untracked files, and so on.

Configuring the Prompt

The PROMPT variable is used to define the format and content of the prompt in the Zsh shell.

# Prompt (aka PS1)
PROMPT="%B%F{014}%n%f%b %F{015}in%f %B%F{011}%2~%f%b \$vcs_info_msg_0_ $ "

Let’s break it down:

  • %B: Starts bold text formatting.
  • %F{014}: Sets the foreground color to dark gray.
  • %n: Displays the current username.
  • %f: Resets the foreground color.
  • %b: Resets any text formatting, such as bold.
  • %F{015}: Sets the foreground color to light gray.
  • in: A static string that adds the word “in”.
  • %f: Resets the foreground color.
  • %B: Starts bold text formatting.
  • %F{011}: Sets the foreground color to a light cyan.
  • %2~: Displays the last two directories of the current working directory.
  • %f: Resets the foreground color.
  • %b: Resets any text formatting.
  • \$vcs_info_msg_0_: Displays the current Git branch information.
  • $: Represents the traditional command prompt character.
  • " ": Inserts a space.
  • "$": Closes the quotation and appends a literal dollar sign.

Overall, the PROMPT value defines a prompt that includes the username, the word “in,” the last two directories of the current working directory, the current Git branch, and the dollar sign prompt character. It also applies color formatting to specific elements of the prompt, such as the username and directory.

Configuring Colors for different files

LSCOLORS is an environment variable in macOS that specifies the colors to be used for different types of files in the Terminal. It is used by the ls command to colorize the output of file listings.

The value of LSCOLORS is a string of 10 characters, each representing a different file type or attribute, and the color code to use for that file type or attribute. The 10 characters represent the following file types/attributes, in order:

  1. Directory
  2. Symbolic link
  3. Socket
  4. Pipe
  5. Executable file
  6. Block special file
  7. Character special file
  8. Executable with setuid bit set
  9. Executable with setgid bit set
  10. Directory writable to others, with sticky bit

Each of the 10 characters can be set to one of the following color codes:

  • a: black
  • b: red
  • c: green
  • d: brown
  • e: blue
  • f: magenta
  • g: cyan
  • h: light gray
  • A: bold black
  • B: bold red
  • C: bold green
  • D: bold brown
  • E: bold blue
  • F: bold magenta
  • G: bold cyan
  • H: bold light gray
  • x: default color (do not change)

For example, if you want directories to be displayed in blue, symbolic links to be displayed in magenta, and executable files to be displayed in green, you can set LSCOLORS to exfxcxdxbxegedabagacad.

# The command "export CLICOLOR=1" is used to enable colorized output in the 
# terminal when using various command-line tools, such as the "ls" command.

export CLICOLOR=1
export LSCOLORS=GxFxCxDxBxegedabagaced

Summary

In this blog post I have described how to configure the .zshrc file, enabling you to personalize your terminal experience. There are several ways of doing so, that was my piece of the pie. I hope you found it useful!