Wednesday, August 06, 2008

ZSH for productivity

by Prashanth Mohan 6 comments




ZSH is a very powerful unix shell. Its over a year now that I started using ZSH over Bash. So, you might ask what kind of innovation and additional usability can a shell really provide. Well ZSH has a number of distinct advantages associated with it. Some of them are:

  1. Extremely compatible with bash - If you are coming from a bash background this is going to be very important
  2. Spell Correct - Who would have thought how much good spell correction for commentsands could bring
  3. Advanced Tab Completion - ZSH has very very intelligent tab completion. Even more so than you get when you install bash-completion. When there is ambiguity, it shows you a list of possible options to a commentsand. Yes, you read it right, it even prompts and autocompletes options for commentsands
  4. More Regex - ZSH has more powerful globbing features. This is a feature I should learn to use more frequently
  5. Faster - All completion data is stored in hashes, and work extremely fast
  6. Multiple Prompts - Ok this might not be touted as a huge advantage, but the availability of a Prompt on both the left and right side of the screen is extremely useful for me. The Prompts in ZSH are so powerful that an entire blog post has been dedicated to customizing this
  7. And a lot more that I haven't explored yet

My .zshrc file is uploaded to http://prashmohan.googlepages.com/zshrc. I will discuss only relevant parts of the configuration in this blog. On your crusade to perfect your shell configuration, I encourage you to check out http://www.dotfiles.com/index.php?app_id=4 which contains numerous user uploaded configuration files.

Tab Completion

The most significant feature of ZSH is it's superior tab completion. This can be enabled in zsh by adding the following lines to your ~/.zshrc file:

autoload -U compinit
compinit
You would also want to additionally format the completion prompts to your satisfaction. This can be done by using the zstyle commentsand. For instance you might want to enable the description to the expanded options, for this you could use the following zstyle statements:
zstyle ':completion:*:descriptions' format "%B---- %d%b" # Messages/warnings format
zstyle ':completion:*:messages' format '%B%U---- %d%u%b'
zstyle ':completion:*:warnings' format '%B%U---- no match for: %d%u%b' # Describe options in full
zstyle ':completion:*:options' description 'yes'
zstyle ':completion:*:options' auto-description '%d'

Pretty Prompts

I already mentioned, how much I enjoy the prompts in ZSH. ZSH has a unique RPROMPT which appears on the right most edge of the shell. To initialize a nice coloured prompt you add the following lines to your ~/.zshrc:

autoload -U promptinit
promptinit
In order to view the different types of default prompts available you can run "prompt -l". You can then run "prompt prompt-name" in order to initialize the particular prompt. However, you might want to custom tailor your prompt to your liking. I use the following for my prompt:

export PS1="${GREEN}%50<...<%~%#${white} "
export RPS1=" ${white}<%T"
export PS2="%_> "
The colour names are basically environment variable which enable the respective colours at the prompt. You can look at my ~/.zshrc for more details about using colours. I use a White text on Black background terminal. More details on how I spruce up my terminal is available on an earlier post: Cygwin tuning guide.

Key Bindings

I am a complete Emacs junkie and I can't live without the emacs bindings. Add "bindkey -e" to your ~/.zshrc to enable emacs key bindings in your zsh shell. If this isn't enough stimulant for you, ZSH also allows you build key bindings on steroids. For example, I have the following lines in my ~/.zshrc:

bindkey -s '^|l' " | less\n"                   # c-| l  pipe to less
bindkey -s '^|g' ' | grep ""^[OD' # c-| g pipe to grep
bindkey -s '^|a' " | awk '{print $}'^[OD^[OD" # c-| a pipe to awk
bindkey -s '^|s' ' | sed -e "s///g"^[OD^[OD^[OD^[OD' # c-| s pipe to sed
bindkey -s '^|w' " | wc -l\n" # c-| l pipe to less

Automatic Directory Pushing

I believe this feature is also available on bash. But that doesn't stop me from mentioning it explicitly here. Each directory you visit can automatically be added (the equivalent of pushd) to the directory stack by the shell. i.e. to go back to the previous directory you were working in, you could simply type in "popd" and voilĂ . To enable this feature, add the following line to your ~/.zshrc:

setopt autopushd pushdminus pushdsilent pushdtohome pushdignoredups # push directories visited automatically onto stack

Other Random Stuff

Some of the other random tweaks I use is to disable "C-s" (Ctrl + S) from disabling the shell input. In order to do this, add the following lines to ~/.zshrc:

stty stop  '^-'
stty start '^-'
You will also want to add "stty pass8 && bindkey -me" to your ~/.zshrc if you want the terminal to properly recognise your Meta (Alt) Key. If you are using Poderosa, you will also need to go to Tools —> Options –> Operation and Change the "Left Alt key" under Keyboard to "Meta Key".

Some of the good aliases and exports I picked up from the net over time are:
alias emacs-clean='find . -name "*~" -exec rm {} \; -or -name ".*~" -exec rm {} \; -or -name "\#*" -exec rm {} \; -or -name "*.pyc" -exec rm {} \;'
alias ll='ls -laFhG'
alias open="cmd /c"
export LESS="-cisFRXMWP?f%f :std in .?n?m(file %i of %m) ..?ltline %lt :byte %bB?s/%s ..?e(END) ?x- Next\: %x.:?pB%pB\%..%t"
export LESSCHARSET=utf-8

Most of the stuff in my config file has been obtained over the Internet from various other like minded souls who were willing to share their way to glory. My initial ZSH config was provided by Shastry, and I hope, this post will compel you to make changes of your own and share it with the world.

My Files:

Other good resources on ZSH config tuning are available at:
Technorati Tags: ,,

Share this post:
Design Float | StumbleUpon | Reddit | Delicious | Facebook | Google Bookmarks
Comments 6 comments
Prashanth said...

Original comment by :jczeus

eric, you are right. I read the section "Managing Directories with the Shell" in chapter 8 of "From Bash to Z Shell" (Apress), where the things you mentioned are also explained. Very useful indeed!

Being lazy, I'll make an alias for "dirs -v", though.

BTW, here is a nice alias I found in "Perl Hacks" (O'Reilly):

alias realias='$EDITOR ~/.aliases; source ~/.aliases'

Prashanth said...

Original comment by :jczeus

I don't quite see the advantage of automatic directory pushing. If you want to return to the previous directory, you can do it with "cd -". I only use pushd if I want to "bookmark" a directory, after which I can change dirs a lot and then return via popd. I would loose this feature with automatic directory pushing.

Prashanth said...

Original comment by :markus

The main thing that kept me from really learning zsh - and i think zsh is the better shell in total - is that it seems a lot more complex than bash.
These days I try to strive for acceptable simplicity. It is why I gave up mastering vim - i use the basics, but if possible I just use a simple graphical editor where I dont need to learn more and more to do what I want to do.

Prashanth said...

Original comment by :eric

jczeus,

the advantage of pushd is that it's an indexed array and you can switch to any entry in that array. Do this:

pushd several directories
run dirs -v to see a verbose listing
then pushd +n, where n is a number in the listing.

It sounds like you've been using pushd only to store one previous location (like M+/MR on a calculator) -- much more is possible.

Prashanth said...

Original comment by :eric

markus, in my experience, the productivity gains associated with mastery of powerful, customizable tools make them well worth the investment of time.

Anonymous said...

Your blog looks awful in Firefox 3.0.10.
You should do some CSS tweaking...
Thanks for the config files though... Have something to start with.