Bilbo and Gandalf


Ala Calvin and Hobbes. (Found on Twitter, but I can’t find the tweet anymore.)


Wordy Nerdy Zsh Prompt


I’ve been using zsh has my primary shell since attending Überconf last July in Denver Colorado. For all intents and purposes it’s a superset of the venerable bash shell. I’ve also been using oh-my-zsh, which is a community driven framework for managing your zsh configuration.

Yesterday evening I refactored my prompt using Steve Losh’s My Extravagant Zsh Prompt posting as a jumping off point. The end result is a nicely colorful, informationally dense prompt. In addition to showing me what machine I’m on, it displays the current working directory, the Ruby version, and information about source control should the working directory contain either a Git, Mercurial (hg), or Subversion (svn) repository.

A picture, or screen shot, is worth a thousand words.

Prompts

And here’s an annotated image that explains all the parts and pieces.

Annotated prompts

##What You’ll Need

##Create an oh-my-zsh theme I copied the Soliah theme when I started with oh-my-zsh originally. Over time I’ve completely modified it to suit my tastes. Browse through the theme offerings and find one you like. Make a copy and give it a unique name. I named mine after my domain, or zanshin.zsh-theme.

You can grab a copy of my theme file from my dotfiles repository on Github.

##The Prompt From left to right my prompt shows me:

  • The user name I’m currently logged in under
  • The hostname of the machine I’m currently at
  • The path to the current working directory

If there is a source control repository present at the working directory, git, hg, or svn, information about the state of the repository is shown next.

For Git repositories the prompt character changes to a ± and this information is shown:

  • The branch name
  • A [dirty] flag if there are tracked but not committed changes
  • A [untracked] flag if there are untracked changes present

For hg repositories the prompt character changes to a and the following information is shown:

  • The branch name
  • The location of the checkout relative to the tip

For svn repositories the prompt character changes to a and the following information is shown:

  • The trunk, branch, or tag currently checked out
  • The revision number
  • And a [dirty] indicator if there are uncommitted changes

##Right Prompt Zsh supports the idea of a right prompt and I’ve made use of this to show the current Ruby version. I’m using rbenv to manage my Ruby versions. The presence of a .rbenv-version file triggers changing the Ruby in effect. My right prompt queries rbenv to determine what to display.

RPROMPT='%{$fg[red]%}$(rbenv version-name)%{$reset_color%}%'

##Subversion Prompt Steve Losh’s prompt works beautifully as-is for git and hg repositories. I wanted to extend my prompt to work for subversion repositories since my employer is subversion-based. I got the bulk of my svn prompt from this Landon Fuller gist.

{% gist 1156969 %}

I stripped out some of his code, paring it down to just the bare essentials to display svn information. What his prompt script didn’t provide was a way to indicate whether or not the working directory had uncommitted changes. Using output from the bash prompt builder as an example I was able to add a test for uncommitted changes.

##Source Code Here’s a copy of the complete zsh-theme I’m using.

{% raw %}
# ----------------------------------------------------------------------------
# Using bits from Steve Losh
#	http://stevelosh.com/blog/2010/02/my-extravagant-zsh-prompt/
# ----------------------------------------------------------------------------

# ----------------------------------------------------------------------------
# Shows little symbol '±' if you're currently at a git repo,
#                     '☿' if you're currently at a hg repo,
#                     '⚡' if you're currently at a svn repo,
#                 and '○' all other times
# ----------------------------------------------------------------------------
function prompt_char {
    git branch >/dev/null 2>/dev/null && echo '±' && return
    hg root >/dev/null 2>/dev/null && echo '☿' && return
	svn info >/dev/null 2>/dev/null && echo '⚡' && return
    echo '○'
}

# ----------------------------------------------------------------------------
# hg prompt
# depends upon ~/Projects/hg/hg-prompt
# ----------------------------------------------------------------------------
function hg_prompt_info {
    hg prompt --angle-brackets "\
< on %{$fg[magenta]%}<branch>%{$reset_color%}>\
< at %{$fg[yellow]%}<tags|%{$reset_color%}, %{$fg[yellow]%}>%{$reset_color%}>\
%{$fg[green]%}<status|modified|unknown><update>%{$reset_color%}<
patches: <patches|join( → )|pre_applied(%{$fg[yellow]%})|post_applied(%{$reset_color%})|pre_unapplied(%{$fg_bold[black]%})|post_unapplied(%{$reset_color%})>>" 2>/dev/null
}

# ----------------------------------------------------------------------------
# svn prompt
# based on: https://gist.github.com/1156969
# with help from: http://andrewray.me/bash-prompt-builder/index.html
# ----------------------------------------------------------------------------
function svn_prompt_info {
	# Set up defaults
	local svn_branch=""
	local svn_repository=""
	local svn_version=""
	local svn_change=""

	# only if we are in a directory that contains a .svn entry
	if [ -d ".svn" ]; then
		# query svn info and parse the results
		svn_branch=`svn info | grep '^URL:' | egrep -o '((tags|branches)/[^/]+|trunk).*' | sed -E -e 's/^(branches|tags)\///g'`
		svn_repository=`svn info | grep '^Repository Root:' | egrep -o '(http|https|file|svn|svn+ssh)/[^/]+' | egrep -o '[^/]+$'`
		svn_version=`svnversion -n`

		# this is the slowest test of the bunch
		change_count=`svn status | grep "?\|\!\|M\|A" | wc -l`
		if [ "$change_count" != "       0" ]; then
			svn_change=" [dirty]"
		else
			svn_change=""
		fi

		# show the results
		echo "%{$fg[blue]%}$svn_repository/$svn_branch @ $svn_version%{$reset_color%}%{$fg[yellow]%}$svn_change%{$reset_color%}"

	fi
}

# ----------------------------------------------------------------------------
# git prompt variables
# depends on using Steve Losh fork of oh-my-zsh
# ----------------------------------------------------------------------------
ZSH_THEME_GIT_PROMPT_PREFIX=" on %{$fg[blue]%}"
ZSH_THEME_GIT_PROMPT_SUFFIX="%{$reset_color%}"
ZSH_THEME_GIT_PROMPT_DIRTY="%{$fg[yellow]%} [dirty]"
ZSH_THEME_GIT_PROMPT_UNTRACKED="%{$fg[yellow]%} [untracked]"
ZSH_THEME_GIT_PROMPT_CLEAN=""

# ----------------------------------------------------------------------------
# zee prompt (ha ha)
# ----------------------------------------------------------------------------
PROMPT='
%{$fg[blue]%}%n%{$reset_color%} at %{$fg[yellow]%}%m%{$reset_color%} in %{$fg[green]%}${PWD/#$HOME/~}%b%{$reset_color%}$(hg_prompt_info)$(git_prompt_info)$(svn_prompt_info)
$(prompt_char) '

# ----------------------------------------------------------------------------
# rubies are red, and so my Ruby version is too
#----------------------------------------------------------------------------
RPROMPT='%{$fg[red]%}$(rbenv version-name)%{$reset_color%}%'

{% endraw %}


Formula One Car on Ice and Snow at Nürburgring


The chief driving instructor at Nürburgring takes a F1 car out for a spin – on ice and snow. The second half of the video is better as it doesn’t have the cheesy music sound track.

For comprison sake, here’s the fastest lap ever done.

And, just to be complete, here’s a motorcycle lap of the same circuit.


Dr. Henry Jones Denied Tenure


(via: @ihnatko)


Switching From Rvm to Rbenv


Since I am reinstalling everything on my machine this week I decided to switch from RVM to rbenv. The biggest reason for the switch is to try something new. Also, rbenv doesn’t fiddle with commands like cd in order to work.

##Removing rvm
Removing rvm is dead simple and necessary as the two won’t co-exist nicely.

$ rvm implode

You may also want to run

$ gem uninstall rvm

##Installing rbenv
I used brew, but you can installing manually too if you like.

$ brew install rbenv
$ brew install ruby-build

ruby-build is a plug-in that allows for easier building of Rubies. Once the two brew commands are done you will need to add the following to your bash or zsh profile:

eval "$(rbenv init -)"

##Getting a Ruby
Downloading and building a Ruby is simple:

$ env CC=/usr/bin/gcc rbenv install 1.9.3-p125 

As of version 4.2, Xcode is LLVM-only and no longer includes GCC. You can install GCC with these binary packages on Mac OS X: https://github.com/kennethreitz/osx-gcc-installer/downloads. Once you’ve got a working gcc compiler in place, the env CC=/usr/bin/gcc specifies its location. And 1.9.3-p125 is the version and patch level of Ruby to compile.

##Displaying Ruby Information in your Prompt
Adding a display of the current Ruby version to my zsh prompt was also easy. I simply embedding the following into my prompt:

rbenv version-name

##Setting Ruby Version Setting the Ruby version to use globally or for a project is also simple. To set the global Ruby version issue a command like this:

$ rbenv global 1.9.3-p125

You can override the global version on a per project basis like so:

$ rbenv local 1.9.2-p290

Both of these commands result in a .rbenv-version file being written that contains the appropriate version indication.

The README file for the rbenv repository on Github lays all of this and more out very nicely.


Formatting and Reinstalling Mac OS X Lion


Last week I rebuilt my work desktop, a 27" iMac, in an effort to get the new SSL VPN client from Cisco to work without causing a kernel panic. This was successful and so I repeated the process on my personal laptop as it also panciked after 30 seconds of connection via AnyConnect.

Rebuilding a TimeMachine supported work computer is one thing. Rebuilding your personal computer – home to all your pictues, documents, and other assorted bits of digital flotsam – is a vastly more stressful endevor.

I started by making a bootable copy of my hard drive using Carbon Copy Cloner. Knowing that a complete copy of my hard drive would take hours I started the process late Saturday evening and went to bed after making sure it was running properly. Sunday morning the process had completed.

Next I verified that the clone was bootable. Restarting my MacBook Pro while holding down the Option key I was able to select which drive to boot from. The clone booted perfectly, if a bit slower than the regular hard drive. After rebooting again to the internal hard drive, I made sure I could mount the FireWire drive and access its contents.

Inserting a DVD I made for the iMac project, that contains a bootable copy of Mac OS X Lion, I rebooted the computer again, this time holding down the C key to boot from the optical drive. Using Disk Utility I crossed my fingers and formatted the drive. Having crossed the Rubicon I then spent the rest of Sunday and a good chunk of Monday rebuilding my machine.

The process, while time consuming, as been straight forward and relatively easy. As I noted yesterday, having a Github repository with my primary configuration files made getting much of my daily use environment reestablished far easier. Having learned from past experience I kept notes in Evernote as I went along – should I ever need to repeat this process I’ll have a recipe to follow.

Here then, for posterity, are my notes.

##Saturday, March 3, 2012

  • Backed up computer using CarbonCopy Cloner

##Sunday, March 4, 2012

  • Verified backup was bootable and that it was readable from laptop
  • Booted using bootable Lion DVD
  • Formatted hard drive
  • Installed Lion
  • Completed initial setup, including iCloud setup
  • Opened Safari - iCloud sync of book marks worked
  • Downloaded and installed Cisco AnyConnect client 2.5.2019
  • VPN connection works and is stable. Yay! \o/
  • Downloaded and installed Google Chrome
  • Installed Alfred via App Store
    • configured Alfred
  • Installed Evernote via App Store
    • Synchronized Evernote
  • Installed Xcode - need the compiler for RVM and brew
  • Changed shell default to zsh
  • Renamed hard drive and computer
  • Downloaded Xcode command line tools
  • Installed Homebrew package manager
  • brew install git
  • Installed iTerm 2 1.0.20120203
  • Ran software update
    • iTunes 10.5.3
    • AirPort Utility
  • Installed Growl via App Store
  • Installed RVM
    • rvm install 1.9.2-p290 –with-gcc=clang – Xcode 4.3 gcc doesn’t work
  • Installed Dropbox
    • Started dropbox sync
  • Installed IntelliJ IDEA 11 Community Edition
    • which required installing Java for Mac OS X 10.7 Update 1
  • Installed Kindle via App Store
  • Installed Skitch via App Store
  • Opened Address Book - verified that iCloud sync worked
  • Installed GeekTool via App Store
  • Installed Marked via App Store
  • Installed Adium 1.5rc4 beta
    • Added Twitterrific buddy list theme
    • Added ymous message style theme
    • Added jabber, GTalk, and Yahoo! accounts
  • Pinned dock to start (upper) corner on left side of screen
    defaults write com.apple.dock.pinning -string [start | middle | end] killall Dock
    • Set hidden on
  • Created src directory in home
  • Cloned Soloraized color repository into src directory
  • Configuring iTerm 2
    • Set window size to 30 x 115
    • Importing Solarized Dark theme
  • Generating new ssh public/private key pair
    • Copied new public key to Github
  • Cloned dotfiles repos and setup symbolic links
  • Cloned oh-my-zsh and set up theme
  • Installed 1Password
    • connected to dropbox stored repository
  • Installed XMarks
    • on Chrome
    • on Safari
  • Installed Twitterrific 4.4.6
  • Installed iPulse 2.1.10
  • Copied from backup to hard drive
    • Documents
    • EBooks
    • Manuals
    • Movies
    • bin
    • src
    • Sites
    • Projects
  • Installed TextMate 2 alpha
    • Applied license
    • Downloaded Solarized theme
  • Purchased iPhoto from iLife 11 as Lion doesn’t come with it
    • Copying old iPhoto library package and replacing new one
    • Restarted iPhoto - allowing it to upgrade the iPhoto database
  • Copied all non-iPhoto images from backup to hard drive
  • Installed NetNewsWire
  • Stopped and restarted VPN Connection successfully
  • Copied Reeder app from back up to hard drive – it works.
  • brew install MacVIM
    • Using –with-ruby-command=/usr/bin/ruby
      • this is still failing….

##Monday, March 5, 2012

  • Setting up Mail accounts
  • Installed SpamSieve
  • Starting iTunes migration
  • Installing 1Password browser extensions
    • Chrome
    • Safari
  • Installing Fetch
  • Downloading purchases from iTunes Store
    • Music
    • Apps
  • Installed MagicPrefs
  • Installed Microsoft Office 2011 for Mac (32-bit)
    • Ran Office updater
  • Installed F.lux
  • Installed GitHub for Mac 1.2
  • Installed SourceTree via App Store
  • Installed HandBrake
  • Installed Sparrow Lite via App Store
    • Configured Gmail accounts
  • Running bundle install for Octopress sites
  • Installed POW
    • setting symbolic links for Octopress sites
  • Copying public ssh key domain host to allow for password-less access

##Tuesday, March 6, 2012

##Epilogue

There are a few more tasks yet to complete. I need to install Portal and Portal2 again, and set up Sibelius. And I’m still tweaking various fonts sizes, Growl notification settings, et cetera.

Wiping my hard drive and starting over has resolved the issue of kernel panics when running AnyConnect. However this solution didn’t solve the problem. I don’t know what was common to both the iMac and MacBook Pro that caused the crashes. I’ve got another MacBook Pro that also has Lion installed and it works perfectly with the new AnyConnect client. My best guess is that there was some low-level residue left over from installing/removing software, and or from migrating from Snow Leopard (and Leopard before that). It was a heavy handed solution that ends the problem.


Splitscreen: A Love Story


(via: @benhemmersley)


Best Repository Ever


Two times now in the past few days I have wiped out a hard drive and started over by reinstalling the operating system and all the applications and settings I wanted. Both times I benefited hugely thanks to a small Github repository I created for myself.

That repository holds many of the configuration files that some of my software tools use, the so-called “dotfiles”. With a simple git clone command followed by a couple of ln -s commands to link the files into place I was able to recreate my zsh environment, setup my global Git configuration and ignore files, configure Vim, and load my TextMate 2 properties.

Originally I created the dotfile repository as an exercise in being nerdy. After this past weekend that exercise has more than paid for itself.


A Clean Slate


tl;dr: Kernel panics caused by Cisco AnyConnect VPN client are tough to resolve. I had to format the drive and start over with a fresh copy of Mac OS X Lion.

My employer, Kansas State University, has recently improved the security of our network by upgrading from an IPSEC VPN to an SSL VPN. The new VPN required a new client and we were all given a link to the proper Cisco AnyConnect image to use. In my case the new client caused a kernel panic approximately 30 seconds after a connection was established.

Over the course of the past two weeks I have tried a number of things to resolve this situation. Some of these ideas were my own and others came from various system administrators and or the security team. The list is more or less in the order I attempted each fix.

I tried:

  • Removing the previous Cisco VPNClient by running the /usr/local/bin/vpn_uninstall script
  • Removing, and re-installing the new AnyConnect client
  • Creating a new user account and installing the AnyConnect client there
  • Reseting the PRAM
  • Disabling IPv6
  • Reinstalling Lion
  • Installing the latest AnyConnect Client (3.0.5080)
  • Removing VirtualBox
  • Reseting the SCM Reseting the SCM was something I tried based on this thread on Apple Support.

After each attempt my computer would again kernel panic after 30 or 31 seconds. To make this story more interesting, I actually was trying this on three different Macintosh computers. A 27" mid-2010 iMac, a 15" mid-2009 UniBody MacBook Pro, and a 15" 2008 MacBook Pro. All three machines were running the same build of OS X 10.7.3, build 11D50. By and large they have the same applications installed and are setup similarly. The 2008 MBP worked with AnyConnect, both the iMac and the 2009 MBP failed to work with the new VPN client.

As the iMac has a SSD boot drive I focused most of my testing effort on that machine – the reboot following each successive kernel panic was much faster than on the MacBook Pro’s spinning drive.

By examining the system.log leading up to the kernel panic one of the security guys identified a potential problem with Bonjour. The error message, shown below, seemed to indicate that the advertising of Bonjour services might be the issue.

mDNSResponder[17]: mDNSPlatformSendUDP sendto(9) failed to send packet on InterfaceID 0000000000000005   en0/6 to FF02:0000:0000:0000:0000:0000:0000:00FB:5353 skt 9 error -1 errno 13 (Permission denied) 140204455605799

He also found a set of instructions that showed how to disable the Bonjour DNS Responder. Trying this actually seemed to work at first. My computer didn’t kernel panic at 30 seconds, although the connection timer stopped at 00:30. The kernel panic came when I tried to close the connection.

With no more ideas I decided to back up the drive and install a fresh copy of Lion. While I’ve only had this iMac for about a year, I migrated from the previous Mac Pro. This means there are files and settings that were created under Tiger, and which have migrated through Leopard and Snow Leopard on their way to Lion. In other words, the amount of cruft in the file system was unknown.

After burning a bootable DVD with the Lion installer the install process took about an hour. Once I complete the initial setup I downloaded the AnyConnect installer and installed the client. Lo and behold, the connection didn’t cause a kernel panic. Not at 30 seconds, not at 5 minutes. Not at all. (So far.)

Going forward my plan is to carefully re-add the software I need to my iMac, testing the VPN stability along the way. The ideal situation would be to discover some incompatible software or setting – something that I can rectify on the MacBook Pro, avoiding the need to back it up, wipe its drive, and re-install Lion.


Elbow Update


This morning I had a consultation with the orthopedic surgeon regarding my right elbow. Four weeks ago I injured it pulling myself up out of a reclined reclining chair. While some range of motion has returned, the healing process has been slow and therefore concerning.

The appointment today was good. The short answer is “synovial inflammation”.

The long version goes like this.

I have lots of arthritis calcifications in my elbow. The bone in your upper arm, the humerus, has a niftily little notch where the partial socket on the ulna fits when your arm is straight. On my right arm that notch is filled in (and then some) with calcifications. This is likely what has prevented me from straightening my arm for most of the last 20 years.

There are also calcifications on the rim of the partial socket on the ulna that may be interfering with a full range of motion.

The doctor (whom both Sibylle and I liked) explained that there is a difference between “normal” and “functional”. What I have had for a very long time now is an arm that is fully functional but has less than normal range of motion. Medically you can have down to just 100º of range of motion and still be considered functional. Until I hurt my arm four weeks ago I’d guess I had close to 160º of range of motion – I couldn’t touch my shoulder and not quite fully extend my arm.

Since injuring my arm four weeks ago I’ve lost about 30º when I extend my arm. If I hold both arms out to my sides, palms up, my left arm is parallel to the floor and my right arm looks like I’m midway through directing traffic. Trying to straighten my arm further hurts.

The doctor wants to approach this conservatively. We are going to medicate it with twice-a-day does of a 500mg of Naproxen for 30 days, and I’m going to have PT on the arm starting Friday. Hopefully the PT will include some ultrasound to reduce inflammation of the soft tissues involved.

I go back in six weeks for a follow-up. If at that time I’m still sore and still haven’t returned to my pre-injury functionality, then we’ll consider surgery. It is possible to perform an arthroscopic procedure on the elbow and “burr” away the calcifications. However, as the doctor put it, “there are a 100 ways I can make your arm worse and only a couple that will make it better.”

So, pain meds, PT, and wait and see.

As for the “you have a weird elbow” comments from my primary care physician, it seems that she was misreading the x-ray. The images are of a three-dimensional structure layered onto a two-dimensional film. With arthritis calcifications obscuring some details and out-right altering the appearance of others, she simply mis-interpreted the image.