Effective shell on Mac OSX
If you are a macOS owner and active user that spends good amount of time in the shell, you may notice OSX Shell by default is bear bone and not very productive to use on a daily bases.
Question is how we can make OSX shell more productive?
The first step is to install/deploy new terminal emulator 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.
iTerm2 we can download from the official Web Site.
iTerm2 provides with a vast list of features like Split Panes, Search, Autocomplete, Split Panes, Instant Replay, etc. And all is documented on the official Documentation Page.
The second step in our journey to install Xcode that is an integrated development environment for macOS and have many useful tools.
Just running below command in the iTer2 will install Xcode.
xcode-select --instal
Next is to deploy the Homebrew as a package manager for OSX that we can use to install and update opensource software applications.
Homebrew is the most used package manager for Apple macOS
Installation is a straight forward process to run below command in iTem2.
/usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"
Once we have Homebrew install let update.
brew update
brew upgrade
OSX by default comes with Python 2.7 installed that very soon will be out of support cycle, the good idea is to update to the latest version of Python using brew in below steps and in addition to deploy the newest version of git, 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 additional useful python packages.
sudo pip3 install pygments
sudo pip3 install powerline-status
Now let’s make our shell shine.
Add below lines to your ~/.bash_profile that will execute ~/.bashrc during the terminal launch
[[ -f ~/.bashrc ]] && . ~/.bashrctest -e "${HOME}/.iterm2_shell_integration.bash" && source "${HOME}/.iterm2_shell_integration.bash"
We can now make our bash prompt more colorful and useful by having bash_completion. In ~/.bashrc file add below lines.
# ~/.bashrc# If not running interactively, don't do anything
[[ $- != *i* ]] && returnif [ -f /etc/bashrc ]; then
. /etc/bashrc
fiif [ -f /etc/bash_completion ]; then
. /etc/bash_completion
fi[ -z "$PS1" ] && returnif [[ ${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 the bash Ex. history aliases some color for man pages and nice color outputt for less and cat commands.
Add below lines to your ~/.bashrc file
export EDITOR=vimexport 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 less for ~/.vimrc
Let’s enhance our command history, instead of cycling with Up and Down arrows 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 typed ls and using Up and Down arrows keys, you can navigate through past command conditions you used.
Create a file in home directory .inputrc and add below 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 the git user and use git CLI from the shell, it is nice to know in what branch you are without typing every time git branch and have a good completion.
Download both files from below 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
And add into ~/.bashrc
# git completion
source ~/.git-completion.bash# git prompth
source ~/.git-prompt.sh
One more tool very useful if you spend time in the shell is tmux.
From Wikipedia,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 onset -g prefix2 C-a # GNU-Screen compatible prefix
bind C-a send-prefix -2
unbind C-b # Unbind original key activisioinset -q -g status-utf8 on # expect UTF-8 (tmux < 2.2)
setw -q -g utf8 onset -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 windowssetw -g automatic-rename on # rename window to reflect current programset -g renumber-windows on # renumber windows when a window is closedset -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 timeset -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# toggle mouse
#bind m run "cut -c3- ~/.tmux.conf | sh -s _toggle_mouse"# 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 whiteset -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.
What is fish — The friendly interactive shell (fish) is a Unix shell that attempts to be more interactive and user-friendly.
Let’s start by installing fish shell and 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, and we are just started.
To make the fish look even better, let’s install powerline and fonts
sudo pi3p 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
sudo nano /etc/shells#add /usr/local/bin/fish to your list of shells/bin/bash
/bin/ksh
/bin/csh
/bin/sh
/bin/zsh
/bin//usr/local/bin/fishchsh -s /usr/local/bin/fish
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 1set -x EDITOR vimset -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 in line with our shell theme and functionality.
The first step is to install vim-plug as 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
Once vim-plug ins deployed we can proceed to install rest of neede plugins like nerdTree, vim-airline, vim-fugitive, etc.
Edit your ~/.vimrc config file for vim and add below 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=1let NERDTreeShowHidden=1
Open vim and run in vim command :PlugInstall this will install all plugins defined in ~/.vimrc
the rest of ~/.vimrc with some neat configuration options can be found at https://github.com/mudrii/.files/blob/master/HWD_Mac/.vimrc
Few more useful apps you can install make use of like like ranger as file-manager in the shell terminal, bat as a replacement for cat, htop console process viewer manager, fd replacement for find, p7zp advance archiver
brew install bat fd ranger p7zip htop
All configuration files used in this article you can find at https://github.com/mudrii/.files/tree/master/HWD_Mac