Customize Shell on Mac OSX
Get the shell you deserve!
Join the DZone community and get the full member experience.
Join For FreeIf you're an active Mac user that spends a good amount of time using shell, you may have noticed that the OSX Shell by default is bear bone and not very productive to use on a daily bases.
The question is, how we can make OSX shell more productive?
Getting Started
Install/Deploy iTerm2
iTerm2 is a replacement for Terminal and the successor to iTerm that brings multiple new features and optimizations that can make users more efficient.
We can iTerm2 download from the official Web Site.
iTerm2 provides features, including Split Panes, Search, Autocomplete, Split Panes, Instant Replay, etc. You can read more on their official Documentation Page.
You may also like: Implement a Command-Line Shell by Using Command Dispatcher in Python.
Install Xcode
Just running below command in the iTer2 will install Xcode.
xcode-select --instal
Deploy Homebrew
Homebrew is the most used package manager for Apple macOS
Installation is a straight forward process. Simply run the following command in iTerm2.
/usr/bin/ruby -e "$(curl -fsSLhttps://raw.githubusercontent.com/Homebrew/install/master/install)"
Once we have Homebrew installed, we can update it.
brew update
brew upgrade
OSX by default comes with Python 2.7 installed, so we're going to update to the latest version of Python using brew. Then, we're going to deploy the newest version of git and vim and install neovim as a potential replacement for vim. In addition, we will install a few more useful packages that come into the light later
brew install python git neovim coreutils inetutils
brew install vim --env-std --override-system-vim
python --version
git --version
As for Python, we can use pip to install to add any other packages/modules we may need.
pip3 install pygments
sudo pip install powerline-status
Now, let's make our shell shine.
Add the following lines to your ~/.bash_profile
that will execute ~/.bashrc
during the terminal launch.
[[ -f ~/.bashrc ]] && . ~/.bashrc
test -e "${HOME}/.iterm2_shell_integration.bash" && source "${HOME}/.iterm2_shell_integration.bash"
We can now make our bash prompt more colorful and useful by adding bash_completion
. In the ~/.bashrc
file, add the following code.
# ~/.bashrc
# If not running interactively, don't do anything
[[ $- != *i* ]] && return
if [ -f /etc/bashrc ]; then
. /etc/bashrc
fi
if [ -f /etc/bash_completion ]; then
. /etc/bash_completion
fi
[ -z "$PS1" ] && return
if [[ ${EUID} == 0 ]] ; then
PS1='\[\e[01;31m\]\h\[\e[01;34m\] \W \$\[\e[00m\] '
else
PROMPT_COMMAND='__git_ps1 "\[\e[01;32m\]\u@\h\[\e[01;34m\] \W\[\e[00m\]" " \\\$ "'
fi
Now, we can configure the rest of bash (e.g. history aliases some color for man pages and nice color output for less and cat commands).
Add below lines to your ~/.bashrc
file
export EDITOR=vim
export HISTSIZE=100000
export HISTFILESIZE=1000000
HISTCONTROL=ignoreboth:erasedups:ignorespace
shopt -s histappend
PROMPT_COMMAND="history -a; history -c; history -r;$PROMPT_COMMAND"
# aliases
alias la='/usr/local/bin/gls --color -lah --group-directories-first'
alias ls="ls -G";
alias cat="pygmentize -f terminal256 -g -P style=monokai";
alias dmesg="dmesg --color=always | less";
alias sudo="sudo -i";
alias vdir="vdir --color=auto";
alias grep="grep --color=auto";
alias fgrep="fgrep --color=auto";
alias egrep="egrep --color=auto";
alias mv="mv -i";
alias rm="rm -i";
alias cp="cp -i";
alias exit="clear ; exit";
alias ping="ping -c3";
# less colors
export LESSOPEN='|pygmentize -f terminal256 -g -P style=monokai %s'
export LESS='-R'
# man pages in colores
man() {
LESS_TERMCAP_md=$'\e[01;31m' \
LESS_TERMCAP_me=$'\e[0m' \
LESS_TERMCAP_se=$'\e[0m' \
LESS_TERMCAP_so=$'\e[01;44;33m' \
LESS_TERMCAP_ue=$'\e[0m' \
LESS_TERMCAP_us=$'\e[01;32m' \
command man "$@"
}
export LC_ALL=en_US.UTF-8
export LANG=en_US.UTF-8
Example for ~/.vimrc
:
Let's enhance our command history; instead of cycling with up and down arrow keys through the entire history of the commands, you can type a command and cycle only for the latest history of the SYNOPSIS Ex. ls-a, ls -la, ls -la / ls -la /etc. Once you type ls, you can navigate through past commands you used.
Create a file in the home directory .inputrc
and add the following entries
#.inputrc
"\e[A": history-search-backward
"\e[B": history-search-forward
"\e[C": forward-char
"\e[D": backward-char
set match-hidden-files off
set page-completions off
set completion-query-items 350
set completion-ignore-case on
set show-all-if-ambiguous on
set bell-style none
TAB: menu-complete
Add below entry to ~/.bashrc
to import settings from ~/.inputrc
.
# import input rc for bash history
export INPUTRC=~/.inputrc
If you are a git user and use git CLI from the shell, it is nice to know what branch you are in without typing git branch
.
Download both files from following links into your home directory ~/
.
curl -O https://raw.githubusercontent.com/git/git/master/contrib/completion/git-completion.bash --output ~/.git-completion.bash
curl https://raw.githubusercontent.com/git/git/master/contrib/completion/git-prompt.sh --output ~/.git-prompt.sh
Then add the following lines into ~/.bashrc
.
# git completion
source ~/.git-completion.bash
# git prompth
source ~/.git-prompt.sh
Another useful tool to keep in mind is tmux.
Tmux is a terminal multiplexer for Unix-like operating systems. It allows multiple terminal sessions to be accessed simultaneously in a single window. It is useful for running more than one command line program at the same time. It can also be used to detach processes from their controlling terminals, allowing SSH sessions to remain active without being visible.
Install tmux.
brew install tmux
Below is the configuration file used to configure tmux ~/.tmux.conf
.
# -- general -------------------------------------------------------------------
set -g default-terminal "screen-256color" # colors!
setw -g xterm-keys on
set -s escape-time 10 # faster command sequences
set -sg repeat-time 600 # increase repeat timeout
set -s focus-events on
set -g prefix2 C-a # GNU-Screen compatible prefix
bind C-a send-prefix -2
unbind C-b # Unbind original key activisioin
set -q -g status-utf8 on # expect UTF-8 (tmux < 2.2)
setw -q -g utf8 on
set -g history-limit 406000 # boost history
# reload configuration
bind r source-file ~/.tmux.conf \; display '~/.tmux.conf sourced'
# -- display -------------------------------------------------------------------
set -g base-index 1 # start windows numbering at 1
setw -g pane-base-index 1 # make pane numbering consistent with windows
setw -g automatic-rename on # rename window to reflect current program
set -g renumber-windows on # renumber windows when a window is closed
set -g set-titles on # set terminal title
set -g set-titles-string '#H:#S.#I.#P #W #T'
set -g display-panes-time 800 # slightly longer pane indicators display time
set -g display-time 1000 # slightly longer status messages display time
set -g status-interval 10 # redraw status line every 10 seconds
# clear both screen and history
bind -n C-l send-keys C-l \; run 'sleep 0.1' \; clear-history
# activity
set -g monitor-activity on
set -g visual-activity off
# -- navigation ----------------------------------------------------------------
# create session
bind C-c new-session
# find session
bind C-f command-prompt -p find-session 'switch-client -t %%'
# split current window horizontally
bind - split-window -v
# split current window vertically
bind \ split-window -h
# pane navigation
bind -r h select-pane -L # move left
bind -r j select-pane -D # move down
bind -r k select-pane -U # move up
bind -r l select-pane -R # move right
bind > swap-pane -D # swap current pane with the next one
bind < swap-pane -U # swap current pane with the previous one
# maximize current pane
bind + run 'cut -c3- ~/.tmux.conf | sh -s _maximize_pane "#{session_name}" #D'
# pane resizing
bind -r H resize-pane -L 2
bind -r J resize-pane -D 2
bind -r K resize-pane -U 2
bind -r L resize-pane -R 2
# window navigation
unbind n
unbind p
bind -r C-h previous-window # select previous window
bind -r C-l next-window # select next window
bind Tab last-window # move to last active window
# Bells
set -g visual-bell on
set -g bell-action any
# Don't lose track of SSH_AGENT etc. from parent environment.
set -g update-environment -r
# Scroll in shell
set -g terminal-overrides 'xterm*:smcup@:rmcup@'
set -wg xterm-keys 1
# Set status bar
set -g status-bg black
set -g status-fg white
set -g status-left-style fg=green
# default statusbar colors
set -g status-fg white
set -g status-bg black
set -g status-style bright
# default window title colors
set-window-option -g window-status-style fg=white
set-window-option -g window-status-style bg=default
set-window-option -g window-status-style dim
# active window title colors
set-window-option -g window-status-current-style fg=white
set-window-option -g window-status-current-style bg=default
set-window-option -g window-status-current-style bright
# Highlight active window
set-window-option -g window-status-current-style bg=red
# Set window notifications
setw -g monitor-activity on
set -g visual-activity on
We change activition key binding for tmux from default Ctrl+b to Ctrl+a similar to screen.
Now that we configure nice-looking bash shell and terminal and learn how to take advantage of the added options we can move to a more advanced terminal and maybe even try to replace bash with more modern-looking shell FISH.
FISH, the friendly interactive shell, is a Unix shell that attempts to be more interactive and user-friendly.
Let's start by installing the FISH shell and a few add-ons like theme manager, oh-my-fish, that can male our FISH fly.
brew install fish
curl -L https://get.oh-my.fish | fish
omf install bobthefish
omf theme bobthefish
omf reload
In the above example, we install FISH and oh-my-fish and deployed "bobthefish" as a theme.
To make the FISH look even better, let's install powerline and fonts.
sudo pip install powerline-status
# install powerline fonts
git clone https://github.com/powerline/fonts.git --depth=1
cd fonts/
./install.sh
To make the FISH shell default when you start terminal use chsh
where you can replace bash with the FISH path
Do not forget to change fonts for iTerm2 to add newly installed fonts.
In Preferences../Profile/Text
You can add an additional configuration option for oh my FISH by editing and adding below lines to ~/.config/fish/config.fish
.
set -g theme_display_git yes
set -g theme_display_git_dirty yes
set -g theme_display_git_untracked yes
set -g theme_display_git_ahead_verbose yes
set -g theme_display_git_dirty_verbose yes
set -g theme_display_git_stashed_verbose yes
set -g theme_display_git_master_branch yes
set -g theme_git_worktree_support no
set -g theme_display_vagrant no
set -g theme_display_docker_machine yes
set -g theme_display_k8s_context yes
set -g theme_display_hg no
set -g theme_display_virtualenv yes
set -g theme_display_ruby no
set -g theme_display_user ssh
set -g theme_display_hostname ssh
set -g theme_display_vi no
set -g theme_display_date no
set -g theme_display_cmd_duration yes
set -g theme_title_display_process yes
set -g theme_title_display_path yes
set -g theme_title_display_user yes
set -g theme_title_use_abbreviated_path no
set -g theme_avoid_ambiguous_glyphs yes
set -g theme_powerline_fonts yes
set -g theme_nerd_fonts no
set -g theme_show_exit_status yes
set -g theme_color_scheme dark
set -g fish_prompt_pwd_dir_length 0
set -g theme_project_dir_length 1
set -x EDITOR vim
set -Ux LC_ALL en_US.UTF-8
set -Ux LANG en_US.UTF-8
For tmux to start with FISH, you can add below two lines to the beginning of the ~/.tmux.conf
.
source /usr/local//lib/python3.7/site-packages/powerline/bindings/tmux/powerline.conf
set-option -g default-shell "/usr/local/bin/fish"
To add aliases you can add to ~/.config/fish/functions/
.
Examples you can find at https://github.com/mudrii/.files/tree/master/HWD_Mac/.config/fish/functions.
Your terminal should look much better with FISH and tmux.
We are not done yet; let's make vim look nice with our shell theme and functionality.
The first step is to install vim-plug, as the vim plugin manager, where can manage, install, and uninstall all needed plugins for vim.
curl -fLo ~/.vim/autoload/plug.vim --create-dirs \
https://raw.githubusercontent.com/junegunn/vim-plug/master/plug.vim
Edit your ~/.vimrc
config file for vim and add the following lines.
call plug#begin()
Plug 'scrooloose/nerdTree'
Plug 'ctrlpvim/ctrlp.vim'
Plug 'bling/vim-airline'
Plug 'tpope/vim-fugitive'
call plug#end()
let g:airline_powerline_fonts = 1
if !exists('g:airline_symbols')
let g:airline_symbols = {}
endif
let g:airline_symbols.space = "\ua0"
let g:airline#extensions#tabline#enabled = 1
let g:airline#extensions#tabline#show_buffers = 0
let g:airline_theme = 'dark'
let g:airline#extensions#hunks#enabled=0
let g:airline#extensions#branch#enabled=1
let NERDTreeShowHidden=1
Open vim and run PlugInstall
. This will install all plugins defined in ~/.vimrc
.
The rest of ~/.vimrc
(with some neat configuration options) can be found here.
With a few more useful apps, you can make use of are ranger as a file-manager in the shell terminal, bat as a replacement for cat, htop console process viewer manager, fd as a replacement for find, and p7zp advance archiver.
brew install bat fd ranger p7zip htop
All configuration files used in this article you can find here.
Further Reading
Published at DZone with permission of Ion Mudreac. See the original article here.
Opinions expressed by DZone contributors are their own.
Comments