My command line prompt
Pluralsight blog Where devs, IT admins & creative pros go for news, tips, videos and more.
3,500+ tech & creative courses authored by experts - unlimited & online Get it now →
January 5, 2012

My command line prompt

By

Advanced Git!

One hour video. More Info…

Your Command Line Dashboard

In 10 years you’ll probably be writing code in a different language, building web apps with a different framework, and wearing a different pair of underwear.

But the command line prompt you use today could still be serving you well.

Many of the elements of my command prompt were snitched from other developers (Christian Neukirchen, Pat Allan, and Ben Hoskings). Here are my goals for my command prompt.

Goals

  • Fast: If I can tell there’s a pause when I open a window or change directories, it’s too slow.
  • Terse: Only show information that will change frequently between projects or between commands. If I always used the same version of Ruby, I would probably remove the Ruby version from my prompt.
  • Mine: I don’t hesitate to customize a script that I copied from someone else. The prompt is not the place to worry about reusable or generalized code. It should be easy to read and change when I need to.

Why ZSH?

I switched to zsh after receiving a one-on-one tutorial from Christian Neukirchen. It has some nice features:

  • Separate prompt for the right and left side of the screen.
  • Inline completion of directories, Git branch names, Rake task names, etc.
  • Easy loop syntax: for f (`ls`) echo $f

Try the source to a simple version of my prompt on GitHub. Or read the explanation below and build your own.

Implementation

Setup

The following configuration directives should be in ~/.zshrc. See the full source for the complete setup.

Run these commands to load zsh’s color variables. You’ll be able to use readable values like $fg[black] instead of cryptic ones like e[0m.

# Colors
autoload -U colors
colors
setopt prompt_subst

Last Command Status

I first saw this technique in Pat Allan’s shell. If the last command exited with a nonzero value, it will print a red Unicode frown: . Successful commands will show a green smiley:

It’s a nice way to quickly see if tests failed or a compilation aborted.

And you’re not limited to ASCII! Use the Unicode snowman, a skull and crossbones, or any other dingbats character.

# Save a smiley to a local variable if the last command exited with success.
local smiley="%(?,%{$fg[green]%}☺%{$reset_color%},%{$fg[red]%}☹%{$reset_color%})"

Current Path

On my local machine I want to show only what’s necessary. So I don’t show the current user, hostname, or anything other than the relative path that I’m currently in.

In zsh, that’s %~.

Assign it to PROMPT to set the left-hand part of the prompt. It occupies two lines: the path is on one line and the previously saved smiley is on the next. $reset_color is a zsh variable that restores your default text color.

# Show the relative path on one line, then the smiley.
PROMPT=
%~
${smiley} %{$reset_color%}’

Git Branch, SHA & Dirty Status

It’s surprisingly difficult to get Git to tell you what branch it’s on. I’ve tried several scripts, including the multi-SCM vcprompt (which worked well).

My current favorite is a Ruby script that prints all kinds of useful information about your Git setup:

  • Current branch name
  • The current SHA (7 characters of it). Useful for anytime you need to get out of trouble with git reset --hard. See the PeepCode Advanced Git video for this and other Git tips.
  • Rebase status (to know if you’re in the middle of a rebase)
  • Dirty status Have any tracked files been edited? A Unicode ✗ is displayed if changes have been made but not committed.

The original script is from Ben Hoskings(requires Ruby 1.9). I edited it to work on Ruby 1.8 and used a brief git-current-branch script (source). The relevant edit is on the last three lines where it specifies a format and colors for the final display.

RPROMPT='%{$fg[white]%} $(~/.rvm/bin/rvm-prompt)$(~/bin/git-cwd-info.rb)%{$reset_color%}'

I chose to make the more important metadata stand out more. The Git branch name and dirty status are more important to me than the Ruby version or the current SHA, so they are a darker shade of grey. Ben uses an @ sign before the SHA, but I replaced it with whitespace.

Ruby & Git metadata.
Ruby & Git metadata.

RVM Config

The name of the current Ruby version as configured by RVM is actually in the previous snippet. It calls ~/.rvm/bin/rvm-prompt and displays it at the left side of the right hand prompt.

Put it Together

The combined prompt looks like this.

# Combined left and right prompt configuration.
local smiley="%(?,%{$fg[green]%}☺%{$reset_color%},%{$fg[red]%}☹%{$reset_color%})"

PROMPT='
%~
${smiley}  %{$reset_color%}'

RPROMPT='%{$fg[white]%} $(~/.rvm/bin/rvm-prompt)$(~/bin/git-cwd-info.rb)%{$reset_color%}'

The important thing is to customize your own prompt and make it work the way you want it to!

Learn the command line, Git, and other great stuff!

Check out our Meet the Command Line and Advanced Git tutorial.

About the Author

is VP of Open Source at Pluralsight. He previously founded PeepCode and is an all around entrepreneur, developer, designer, teacher and athlete. Follow him on Twitter at @topfunky.


Discussion