DEV Community

Cover image for Essential quality of life terminal improvements
jess unrein
jess unrein

Posted on

Essential quality of life terminal improvements

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
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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=" šŸ”Ŗ "
Enter fullscreen mode Exit fullscreen mode

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  raw `grep "something` endraw  and several secondary prompt lines with a knife emoji instead of  raw `>` endraw

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
Enter fullscreen mode Exit fullscreen mode

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 šŸ‘¾ "
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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!

Top comments (18)

Collapse
 
parkerholladay profile image
Parker Holladay

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

Collapse
 
midblue profile image
Jasper Stephenson

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

Collapse
 
parkerholladay profile image
Parker Holladay

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

Thread Thread
 
midblue profile image
Jasper Stephenson

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...

Collapse
 
ex_y profile image
Ashe

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

Collapse
 
thejessleigh profile image
jess unrein

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

Collapse
 
mojo2012 profile image
Matti

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šŸ˜Š

Collapse
 
thejessleigh profile image
jess unrein

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.

Collapse
 
rhymsy profile image
rhymsy

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-...

Collapse
 
mojo2012 profile image
Matti

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

Collapse
 
moopet profile image
Ben Sinclair

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?

Collapse
 
andrewbrown profile image
Andrew Brown šŸ‡ØšŸ‡¦

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'
Collapse
 
awwsmm profile image
Andrew (he/him)

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

#2spoopy4me

Collapse
 
thejessleigh profile image
jess unrein

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!
Collapse
 
midblue profile image
Jasper Stephenson

Ohohoho this is so much fun!

Collapse
 
okash1n profile image
okash1n • Edited

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

Collapse
 
thejessleigh profile image
jess unrein

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

Collapse
 
jeikabu profile image
jeikabu

My terminal is default and sad...