loading...
Cover image for Essential quality of life terminal improvements

Essential quality of life terminal improvements

thejessleigh profile image jess unrein ・8 min read

If you're anything like me, you spend a lot of time in your terminal. I went an embarrassingly long time without customizing anything because I'm fundamentally lazy and didn't want to learn how. However! Improving your terminal experience through configuration is the much more efficient and lazy long term solution. A few minutes now saves you headaches later. Don't be like me and wait a couple years before getting with the program.

I use the MacOS default Terminal app. I don't use zsh or iTerm or Upterm or anything else. I am not fancy. Getting fancy seems like a lot of work. We've already established that I'm lazy. If you disagree, change my mind in the comments!

The Basics

What is ~/.bash_profile?

/.bash_profile and ~/.bashrc are scripts that are executed when bash is invoked.

  • ~/.bash_profile scripts are executed for login shells
  • ~/.bashrc scripts are executed for non-login interactive shells

What does that mean?

Login shells are run with the user logged into the system. It's still an interactive session, because you input commands and the shell reads them from its standard-input. You use login shells for anything where you need user permissions or where you would like the shell to start up with consistent configuration every time.

Non-login interactive shells do not have a user attached to its session. These are good for running automated processes that don't depend on being logged in to run.

By default, new OSX terminal sessions are login shells. I don't run on a Linux machine day to day, but as far as I understand, Linux terminal emulators start up using non-login interactive shells by default.

This post demonstrates a few quality of life improvements that will make your terminal experience smoother and more #aesthetic. These changes are largely in ~/.bash_profile which means that they'll be executed in your login shells, but not in your non-login interactive shells.

What if I already have ~/.bashrc?

You might already have been putting config stuff in ~/.bashrc and just source it in your shell. Also, many people want to keep functionality like usability scripts strictly separate from cosmetic and/or fun improvements. No problem! You don't have to get rid of it. Just include this line in ~/.bash_profile:

source ~/.bashrc

Other files we'll be touching on today

~/.gitconfig
~/.config/neofetch/config.conf
~/.hushlogin
~/.git-completion.bash

Usability Improvements

git completion

One of my biggest pain points was lack of tab completion for git branch names.

Luckily, there's an open source solution available for this.

To take advantage of this you'll need to copy the raw contents of the link above into a local file

curl https://raw.githubusercontent.com/git/git/master/contrib/completion/git-completion.bash -o ~/.git-completion.bash

Now you can just run git-completion.bash in your ~/.bash_profile by including the following command. Get in on that tab completion goodness.

source ~/.git-completion.bash

git commit attribution

Make sure you set user level information in your ~/.gitconfig file. It'll make sure commits are attributed properly, and you can set it and forget it.

[user]
name = mygithubusername
email = my.github.email@example.com

Useful aliases

Sometimes typing all of the characters in a command is just too much. Here are some easy aliases that can make your life a bit better.

Of course, as with any alias, change the name of the alias to whatever will be most useful to you.

# list files
alias la="ls -oa" # show hidden files and format nicely

# change directories
alias ..="cd .."
alias roj="cd ~/projects" # or wherever you store your main project files

# git aliases
alias gdf="git diff"
alias gap="git add -p"
alias gc="git commit -m"
alias gs="git status"
alias gco="git checkout"
alias gul="git pull"
alias gush="git push"
alias gbra="git branch"
alias glog="git log --pretty=format:'%h - %an: %s' --graph" # print out log with hash, author name, status, and include graph info

Oh No Something Broke!

Remember that nice git autocompletion stuff we set up a little bit ago? It's broken with these aliases, which is a huge bummer!

The fix for this is to amend ~/.git-completion.bash. Now, according to a comment in the ~/.git-completion.bash file itself:

This is NOT a public function; use at your own risk.

So, I recommend having a window open where you do NOT source your new ~/.bash_profile and can revert your changes safely if you test them and they don't work.

With that warning out of the way, you can add the following to the bottom of ~/.git-completion.bash to have it play nice with your aliases.

# git complete aliases
__git_complete gdf _git_diff
__git_complete gbra _git_branch
__git_complete gco _git_checkout

Prompt String

I like to keep my prompt string fairly simple because if I overload it with too much information, I end up ignoring it.

parse_git_branch() {
  git branch 2> /dev/null | sed -e '/^[^*]/d' -e 's/* \(.*\)/ (\1)/'
}

PS1="\w | \$(parse_git_branch) 👾 "

PS2=" 🔪 "

There are a couple things going on here. My two favorite things to have in my primary prompt string are my current location, and the active git branch. There's not a builtin function to find the active git branch, so I've defined a function above that will do it.

Here are the components of the actual prompt string (PS1)

  • Current directory (\w)
  • a delimiter character to make it easier to read (|)
  • the git branch (in parentheses for even more visual context) $(parse_git_branch)
  • alien emoji because I think it's cute (👾).

PS1 is the string that you'll generally see in your command prompt. PS2 is the string that will show if you press enter and trigger a secondary line in the command prompt. The default value for PS2 is >.

Here's an example with both my PS1 and PS2 values.

A picture of my terminal reading `grep "something` and several secondary prompt lines with a knife emoji instead of `>`

I like the knife emoji here because I almost never intentionally trigger the secondary prompt string

Cosmetic Improvements

last login

I don't like new terminal windows to start with a last login statement. The last login is whenever I last opened a new terminal window, which is not useful information for me. You can get rid of this line by creating this empty file:

touch ~/.hushlogin

This should work immediately. You don't need to source anything. Next time you open up a new terminal session, you shouldn't see login information. If you ever decide you want login information again, just delete this file.

prompt string colors

The only thing better than a clean and informative prompt string is a clean and informative prompt string with FUN COLORS.

I didn't show you this above because adding color to anything in bash is a pain, so I wanted you to be able to set up your functional PS1 values before tearing your hair out trying to get the colors right.

Here's what my PS1 value actually looks like:

PS1="\e[0;35m\w\e[m \e[0;33m|\e[m \e[0;36m\$(parse_git_branch)\e[m 👾 "

Terminal prompt with current working directory in purple, a yellow vertical pipe, active git branch in cyan, and an alien emoji

So much visual information packed in with these colors!

When you want to assign a color to a part of a string, use the following pattern:

\e[X;Ym text you want to be in a color \e[m

  • \e[ is where the color coding starts
  • X;Y is the color code you're using, which in most cases will be two numbers separated by a semicolon
  • m lets bash know that's the end of the color code and to start processing your stirng
  • \e[m signals the end of the section you want color coded

It's a mess to read, and I know I'm never going to commit this to memory. Check out this comprehensive guide that lists several color codes.

Neofetch

neofetch is a nifty tool that displays information about your system in an aesthetically pleasing and easily accessible way. Want to know which version of your OS you're using, your uptime, or what font you happen to be using in your login shell session? neofetch has all this and more, plus customizable ascii art.

This is really part cosmetic improvement and part usability improvement, but I've put it in the cosmetic section since it will have a big impact on the look and feel of your terminal.

For MacOS you can brew install neofetch. For other operating systems, follow their installation guide. They support tons of operating systems, even obscure ones.

You can set your own ascii art to appear whenever you run neofetch. When it installs, it creates a ~/.config/neofetch directory containing a config.conf file. Go into the file and edit the image_source location to the absolute path of the ascii art you'd like to use. Follow the guide on how to format and color your art.

Here's a picture of my neofetch setup. (Please ignore my borderline absurd uptime I should restart more often).

A screenshot of my terminal output from neofetch, including rainbow ascii art of a demon, operating system and kernel info, uptime, etc.

It's almost Halloween, so I have to show off some spoopy ascii

I have it set so that neofetch runs every time I open a new terminal window. You can do this simply by calling neofetch at the bottom of your ~/.bash_profile.

git colors!

I like a lot of the default colors set by git. git status has red for changes not staged to commit, green for changes to be committed. That sort of thing. But there are other color settings I'm not wild about. I don't love that git status untracked files and unstaged but tracked files are the same color. I don't like that git diff meta information and new lines are both green.

Here's how I've changed my settings. I really like cyan for dark or black backgrounds. bold helps me separate meta information from changes in diff. And I really like reverse and bold for the current branch so that I can identify it quickly in a long list of branches.

[color]
  ui = auto
[color "diff"]
  meta = cyan bold
  frag = magenta bold
[color "status"]
  untracked = cyan
[color "branch"]
  current = cyan reverse bold
  local = green
  remote = yellow

Here are some examples of what these options look like

Git status output with updated color profile

git status with cyan untracked files

Git diff output with updated color profile

git diff with bold cyan metadata, bold magenta fragment data

Git branch output with updated color profile

git branch with green for local branches and reverse cyan for current branch

End result

Here's pretty much what my ~/.bash_profile looks like, all together in one place for anyone who wants to copy it. I recommend you do. These are some awesome settings. Let me know if you have any questions!

. ~/.git-completion.bash

parse_git_branch() {
  git branch 2> /dev/null | sed -e '/^[^*]/d' -e 's/* \(.*\)/ (\1)/'
}


PS1="\e[0;35m\w\e[m \e[0;33m|\e[m \e[0;36m\$(parse_git_branch)\e[m 👾 "

PS2=" 🔪 "

# list files
alias la="ls -oa" # show hidden files and format nicely

# change directories
alias ..="cd .."
alias roj="cd ~/projects" # or wherever you store your main project files

# git aliases
alias gdf="git diff"
alias gap="git add -p"
alias gc="git commit -m"
alias gs="git status"
alias gco="git checkout"
alias gul="git pull"
alias gush="git push"
alias glog="git log --pretty=format:'%h - %an: %s' --graph" # print out log with hash, author name, status, and include graph info

neofetch

Here's my ~/.gitconfig

[user]
name = mygithubname
email = my.github.email@example.com

[color]
  ui = auto
[color "diff"]
  meta = cyan bold
  frag = magenta bold
[color "status"]
  untracked = cyan
[color "branch"]
  current = cyan reverse bold
  local = green
  remote = yellow

Additional Fun Things

Take a look at terminal screenshots that DEV community members have shared in the past.

Do you need more Ryan Gosling on your terminal? I'm fairly certain you do.

GitHub logo koriroys / gosleap

Make Ryan Gosling jump across your screen

Gosleap

Only works on OSX

Usage

ryan gosling jumps across the screen

Installation

Add this line to your application's Gemfile:

gem 'gosleap'

And then execute:

$ bundle

Or install it yourself:

$ gem install gosleap

Contributing

  1. Fork it ( http://github.com//gosleap/fork )
  2. Create your feature branch (git checkout -b my-new-feature)
  3. Commit your changes (git commit -am 'Add some feature')
  4. Push to the branch (git push origin my-new-feature)
  5. Create new Pull Request



Happy Friday! Share your favorite terminal enhancement in the comments below!

Posted on by:

thejessleigh profile

jess unrein

@thejessleigh

Pronouns: they/them | | | Pythonista, cat lover, avid reader, and gamer in Chicago. Tip jar: https://ko-fi.com/thejessleigh

Discussion

markdown guide
 

I notice your ..="cd .." alias. Try autocd=true. You'll never need to type cd again.

 

That one doesn't work for me! Does it not work in stock Terminal?

 

My bad. The command is actually shopt -s autocd. I should have checked my bashrc first.

Just so anyone trying this knows, I had to update my bash to @4+ to get this working!
Here's a handy guide on getting it working:
clubmate.fi/upgrade-to-bash-4-in-m...

 

!!!!!! OMG This is so great!!!!!!! (thanks for sharing this awesome tip!)

 

Ooh. That one is new to me and I’m very excited to try it out. Thanks!

 

If ur really that lazy u should just install oh-my-zsh. It does all the cool stuff out of thr box, plugins r auto updated and u can even sync ur zshrc.
Its has autocomplete for everything, is case insensitive etc. Give it a try!

I was like u for way to longtime until a colleague showed my omz😊

 

I am just so reluctant to learn a whole new thing. I'm busy learning other things and there are only so many things I can focus on! But zsh is definitely on my list of things to check out....at some point.

 

Here for your spare time :)

Jorge use ZSH with Oh My Zsh

I know you probably don't need the setup parts... but a quick parse through the first one and some looks in the second and you'll be off to the races

dev.to/jorge_rockr/my-development-...

dev.to/jorge_rockr/my-development-...

 

There‘s really nothing much to learn, oh my zsh does all for u!
It configures zsh to a point where u might only want to join the theme and nothing else

 

Please ignore my borderline absurd uptime I should restart more often

Nuh-huh. Take pride in your uptime! If you don't need to reboot, why reboot?

 

These are my aliases if its of interest:

alias gst='git status'
alias co='git checkout'
alias ga='git add'
alias gaa='git add .'
alias gr='git rebase'
alias gpr='git pull --rebase'
alias gp='git pull'
alias gh='git push'
alias gd='git diff | vim'
alias gc='git commit -v'
alias gca='git commit -v -a'
alias gb='git branch'
alias mb='deetsm; expm; middleman build'
alias ms='deetsm; expm; middleman serve -p 8080'
alias gba='git branch -a'
alias rgm='bundle exec rails generate migration'
alias rs='deets; exp; bundle exec rails s -b 0.0.0.0 -p 8080'
alias rc='bundle exec rake db:create'
alias rd='bundle exec rake db:migrate'
alias rdd='bundle exec rake db:drop'
alias rdr='bundle exec rake db:rollback'
alias rad='bundle exec rake db:auto:migrate'
alias rr='rake routes'
alias gsw='git add .; git stash save; git checkout master; git pull; git stash apply'
alias ggco='git rebase --continue'
alias ggcs='git rebase --skip'
alias ggca='git rebase --abort'
alias gsl='git stash list'
alias gsp='git stash pop'
alias gsa='git stash apply'
alias gsc='git stash clear'
alias gbl='git branch list'
alias zz='tar -xzvf'
alias exp='cd /home/ubuntu/environment/exampro'
alias expm='cd /home/ubuntu/environment/exampro-marketing'
alias bi='bundle install'
alias bx='bundle exec'
alias gsoft='git reset --soft HEAD^'
alias rrrr='bundle exec rake db:drop; bundle exec rake db:create; bundle exec rake db:migrate; bundle exec rake db:seed'
 

It's almost Halloween, so I have to show off some spoopy ascii

#2spoopy4me

 

The art I use on my other workstation is much friendlier :P

Neofetch output with rainbow ascii art of a ghost saying "Welcome Home"

So cute! So welcoming!
 
 

Can I write a Japanese translation article on my own blog and dev.to?

 

Go for it! Just link it back to the original please. I’m really glad you liked it!

 

My terminal is default and sad...