Sunday, October 3, 2010

Ultimate Tab Completion

I recently switched my default shell to zsh. It has the ultimate tab competition. Watch the video to see how that works. Mostly everything else works the same as bash. I haven't found much if anything to work differently, just the better tab completion features mostly.

How I did it

First I installed zsh!
Next I used Oh My Zsh configuration.
I appended my own customizations to it (the bottom of .zshrc).
I'll explain each, so you can decide if you want to use any of that.

That includes

  • Using shift tab to do the reverse cycle through the tab completion as shown in the video
  • Everything typed by me in bold
  • Allowing comments while typing in zsh (not just scripts)
  • Importing my bash aliases and functions to zsh
  • And the same effect you normally get in Ubuntu when typing a command from a package that isn't installed.

Example of command not found working in zsh:

➜  Desktop  twm
The program 'twm' is currently not installed.  You can install it by typing:
sudo apt-get install twm
zsh: command not found: twm
➜  Desktop 

With the Oh My Zsh configuration, you can change your prompt to some custom pre-made ones. I use the default because I like that one.

The Guide

# You need to apt-get install git-core if you don't already have the git command
$ git clone git:// ~/.oh-my-zsh 
Initialized empty Git repository in /home/phillip/.oh-my-zsh/.git/
remote: Counting objects: 1173, done.
remote: Compressing objects: 100% (591/591), done.
remote: Total 1173 (delta 714), reused 873 (delta 543)
Receiving objects: 100% (1173/1173), 135.71 KiB | 102 KiB/s, done.
Resolving deltas: 100% (714/714), done.
# On the next line, if you don't know how to use vim, replace it with gedit
$ sudo vim /etc/passwd
# Change the line:
#  username:x:1000:1000:Your Name,,,,:/home/username:/bin/bash
# To:
#  username:x:1000:1000:Your Name,,,,:/home/username:/bin/zsh
# The only part you need to change is /bin/bash to /bin/zsh at the end!
$ grep $USER /etc/passwd # This command is just to check that the change was made
$ cp .oh-my-zsh/templates/zshrc.zsh-template ~/.zshrc
# Append these to the end of your .zshrc after the comment about customization 
# Meaning add these 4 lines to the end of your .zshrc

# Customize to your needs...

bindkey '^[[Z' reverse-menu-complete # Reverse tab cycle
zle_highlight=( default:bold ) # Bold everything typed
setopt interactivecomments # Allow comments in interactive mode
command_not_found_handler() {/usr/lib/command-not-found $1} # Good 1 ;)

# If you are using debian lenny, the command-not-found package is not in the repos,
# Otherwise, It works with sid and newer as well as in Ubuntu

# The rest of the guide is optional!
# If you want to use some of my bash functions and aliases, continue
# Otherwise just logout and back in and your shell will be using zsh!
# Also my some of my functions and aliases use things such as hamachi,
# So you must edit the file to add/remove what you want.
# If you don't feel comfortable doing that, stop here, logout and back in!

$ mkdir ~/.bash
$ wget -O ~/.bash/functions_and_aliases
--2010-10-03 22:51:23--
Connecting to||:80... connected.
HTTP request sent, awaiting response... 200 OK
Length: unspecified [text/html]
Saving to: `/home/phillip/.bash/functions_and_aliases'

[ <=>                                                            ] 2,436       --.-K/s   in 0.01s   

2010-10-03 22:51:31 (183 KB/s) - `/home/phillip/.bash/functions_and_aliases' saved [2436]

$ zsh
➜  ~  grep '()\|alias' ~/.bash/functions_and_aliases 
myip() { # Display my external internet IP in one line
pfix() { # Permission fix for apache public_html
hr() { # Hamachi run
hs() { # Hamachi stop
hl() { # Hamachi list only online members/networks
psgrep() { # Results ps grep # Takes one arguement
fixntfs() { # When NTFS won't mount
wifireset() { # Reset the wifi connection in case it quits working
ushred() { # Shred files on my ultimate settings
alias lsonf='lsof -i -n -Pi' # List open network files
alias goog="curl -A Mozilla |html2text -width 80" # Google from the CLI; Needs a little more work
alias hsgrep='history | grep $1' # History grep
# More created aliases
alias autopurge='sudo apt-get --purge autoremove'
alias cd...='cd ../'
alias ...='cd ../../'

➜  ~  
# Append this to the end of your .zshrc after the comment about customization 
# Meaning add this one line to the end of your .zshrc

source ~/.bash/functions_and_aliases # Import bash f(x)'s and aliases

# Be sure to edit that functions_and_aliases file
# To be correct for your computer. For example,
# /dev/sda1 and /dev/sdc1 may not be your ntfs partitions if you dual boot
# If you don't use hamachi vpn, remove those, don't use wifi,
# Then remove the wifireset() {...} function, etc.

➜  ~  source ~/.zshrc

# Now you can use all the functions and alises in that file.
# Also append that source line to your .bashrc if you want to use them in bash
# Here's are two examples
➜  ~  myip
➜  ~  psgrep xchat

chris     2724  0.9  1.7 303568 36356 ?        Sl   19:47   1:44 xchat
phillip  14298  0.0  0.0   7624   908 pts/5    S+   22:56   0:00 grep xchat

GNU Screen and configuration 
(because I used it in the video)

Read here:

Here's my ~/.screenrc
Note: If you use this, change the directories to ones that exist on your computer

hardstatus alwayslastline
hardstatus string '%{= kG}[ %{G}%H %{g}][%= %{=kw}%?%-Lw%?%{r}(%{W}%n*%f%t%?(%u)%?%{r})%{w}%?%+Lw%?%?%= %{g}][%{B}%Y-%m-%d %{W}%c %{g}]'

# Default screens

chdir ~/
screen -t bash    0 /bin/bash
chdir ~/Coding/CS2213
screen -t zsh    1 # will run zsh by default
chdir ~/Hax0r
screen -t zsh     2 # will run zsh by default
chdir ~/
screen -t zsh     3

And then type screen and that config will be loaded.

Visual Recursive Quick Sort

Final Step

Now after you did all that, head to your gym and squat 385 lbs 2 times (or as many as you can till failure)


  1. I'll have to try this: it looks great!

  2. Thank you very much for this post. Lack of command-not-found completion was the last straw that drove me back to bash when I tried to switch to zsh last time. I didn't have time to research how to enable it.

    Tip: use chsh instead of sudo vim /etc/passwd to change your login shell. It will prevent you from making mistakes and being unable to log in.

  3. Great, I'm glad you could benefit from this. sudo twm will not give you the command not found thing, but if you ask in #zsh on Freenode, there's a little code that to get it to do that. However, it acts the same in bash.

  4. I had known about chsh. Thanks for mentioning it. There may be a few who aren't very inclined with Linux that may make the mistake you are speaking of.

  5. Cool, it's very neat..
    it makes shell more powerful and more effective..
    Good job man..

  6. Hi its really very nice blog,very useful information..Mobiles

  7. Cool work ..I think your article its very important and interesting,nice blog.

  8. So informative web site! Large thanks! Thanks for a good time visiting your site. It is really a pleasure understanding a web site like this filled with nice information. Thanks!
    Hotels in Berlin