Four years ago, in April 2009, I joined GitHub. Whenever possible I use ‘zanshin’ as my account name, however someone else had beaten me to that account on GitHub. So I used my fall-back acccount option, ‘zan5hin’.
Periodically I would visit http://github.com/zanshin to see if the account was being used. Other than an initial project that had long since gotten stale, there was no activity. Moreover, there was no profile information so I had no way to contact the erstwhile owner to see if they would be willing to relinquish the account name to me.
This past weekend I sent an email to GitHub support asking for their help in contacting the owner. Here is the email I received today in response to my request:
Hi Mark,
Sure! We happily release unused usernames into the wild. I’ve reviewed this account, and deemed it dusty. I’ve made the username available to you. If you wanted to create an organization, the name will be available. It’s not reserved, though, so someone else might swoop in and take it if you hesitate too long!
You can change your username by going to Account Settings > Account Admin > Change your username.
Be aware, after you change your name, you will need to update the remotes in any local clones of your repos to point at your new repo URL. Please don’t hesitate to let us know if you have any questions or concerns.
Thanks, Sara
Needless to say I immediately changed my account name from ‘zan5hin’ to ‘zanshin’. And started the necessary changes to my remotes.
In case you ever need to change the URL for a remote here’s the command to use:
The Uses This series, and Shawn Blanc’s Sweet Mac Setups series have always intrigued me, so I decided to write one of my own.
Who are you and what do you do?
My name is Mark Nichols. I’m married to Sibylle Kuder, I play violoncello, I hack around with various computer technologies, and I’m an all-around good guy. Professionally I work for Kansas State University as an “Integration Services Coordinator” — dealing with the sometimes messy intersection of differing systems and their needs. Lately I’ve been diving into the world of Vagrant and Chef.
What hardware do you use?
My personal computer is a mid-2009 15” 2009 MacBook Pro with a 2.66 GHz Core 2 Duo processor and 8 GB of RAM. Within the next week the original 320 GB hard drive will be replaced with a new 1 TB drive.
I also have a 16GB iPad Mini that is easily one of the nicest computers I have ever owned. My phone is a 16GB iPhone 5 on AT&T.
My employer provides me with wonderful tools, so I have on my desk a mid-2010 27” iMac with a 256GB SSD and a 1 TB spinning drive. My work laptop is a 13” Retina MacBook Pro, with a 500 GB SSD and 8 GB of RAM. It is the sweetest computer I’ve ever had the pleasure of using.
Tunes in my car are provided via an 8 GB 6th-generation iPod Nano. The car, a 2010 Honda Insight, has the world’s clunkiest iPod interface, but it does let me listen to Zoë Keating on my way to and from work. I have an aging (no longer holds a charge but works fine plugged in) 30 GB iPod that holds most of my music and lives in the corner of the house where I practice my cello, so that I can listen to the pieces I am learning.
For printing we have a newly purchased HP OfficeJet Pro 8600 All-in-One printer/copier/fax/scanner. It’s beautiful, it’s wireless, and it prints like a dream.
At work I use a pair of Apple EarPods to listen to music or videos. At home I use a variety of earbud style earphones, but only when the cat isn’t around. She considers them string with which to be toyed.
Fetch handles my SFTP needs, although I am making more and more use of sshfs for accessing remote drives.
Growl for notifications and Alfred for Cmd-Space-ing things.
TakeFive helps me to control what’s playing, and Cobook gives me access to my contacts.
F.Lux dims my laptop screen at night, and brightens it during the daylight hours.
Dropbox for convenient movement of files between computers, and Git for version control of all my coding projects.
What would be your dream setup?
After spending a couple weeks with the 13” Retina MacBook Pro I would be hard pressed to consider any other machine. Well, maybe the 15” Retina MacBook Pro.
I’d like a dead simple storage system that hung off our router that would let Sibylle backup her Windows-based machines and me back up my OS X-based machines seamlessly. And perhaps a Mac Mini tied to a couple large drives to house all our music and DVD movies.
I’d also like an iPod Classic as it would be large enough to hold my complete collection of music and audio books. But first I’ll need a car with a decent iPod interface.
I’m intrigued by the Sonos Speaker systems, but other priorities have kept that on the someday list.
And someday I hope to be advanced enough on the cello to warrant a really good, old, instrument.
After a year of use the Apple Bumper case for my iPhone 4S developed a tear in one corner. The case is still functional, but I found the tear unsightly and used it as an excuse to get a new case for my phone.
Case shopping can be frustrating. Local merchants are likely to only have the popular cases, many of which are garish, which limits your choices. Shopping on the Internet broadens the pool of cases to choose from, but you can’t “test drive” one. After a visits to BestBuy and the local Verizon store, I used a holiday to visit the nearest Apple store, two hours away in Kansas City. None of the cases really pulled my string, so I continued to use the torn bumper case.
I actually like the look and feel of the iPhone naked, but the glass by itself is slippery and I am always afraid I’ll drop it when it’s not in a case.
It’s the perfect cover for those who have an iPhone, and are not afraid to show it.
It’s not a case, per se, nor is it a sleeve. The best description is that it’s a jacket for your phone. A wonderfully supple Napa leather jacket. The leather is less than a 1/10th of an inch thick and weighs next to nothing at under an ounce. TwelveSouth says that
[r]ather than protecting your iPhone from falling off the side of a cliff, the luxury leather SurfacePad shields your iPhone from more common hazards, like the keys in your pocket.
I’ve had my SurfacePad for just over two weeks now and I could not be happier with it. Rather than hide the beautiful design of the iPhone in a plastic or rubber cover, the SurfacePad accentuates phones presence. The juxtaposition of leather with the metal and glass of the phone is perfect.
It slips into and out of my pocket with ease, but it doesn’t feel slippery at all. The leather protects the front glass, and wraps around the volume control side of the phone’s chassis. The back adheres to the phone with “modern adhesive” that has been used for years on TwelveSouth’s SurfacePad for MacBooks for years. The jacket can be removed a reattached.
The jacket is designed to act as a stand for the phone in landscape orientation. As luck would have it my favorite tuner/metronome app works in landscape orientation, so I use the stand on a daily basis.
For most activities I am unaware of the cover, but I do notice it a bit when making phone calls. I am left-handed when it comes to phone calls, so I fold the cover back completely, which slightly increases the phones thickness. It’s not enough to be objectionable, but I do notice it.
TwelveSouth has minimal branding on the jacket. The bottom of the front cover has a small embossed TwelveSouth logo. Inside the cover, oriented so that you can read it when the jacket is being used as a stand, is the product name, SurfacePad. And hidden away in the hinge of the case, is a repeat of the logo and the company name, TwelveSouth. The understated branding suits me very well as it allows the phone to be the center of attention.
The black leather on my jacket is smooth and unblemished. The interior side is a light grey with a very fine nap. It feels a bit like a high quality lens cloth. The double row of stitching on the back where the hinge is located is well done. There are no lose threads and the stitches are nearly flush with the leather. There is a cutout for the rear facing camera and flash. After two plus weeks of use my jacket is staring to feel broken in – like a favorite leather coat.
At $34.99 this isn’t the least expensive nor the most expensive cover for your iPhone. But in terms of quality, fit and finish, and enhancement to the phone, I don’t think you could find anything better.
At the end of January I received an email asking me if I would be willing to read and review a short book on getting started with Sublime Text 2. The email seemed legitimate and after investigating a little bit I decided to take them up on their offer. Here’s the email:
Hi Mark My name is Dyson D’ Souza and I work for Packt Publishing, a UK-based publishing company specializing in focused IT books. We have recently published a book Sublime Text Starter, and I was wondering if you’d be interested in taking a look at the book and sharing your comments on your blog and on Amazon.com. A few details about the book: book composes of around 40 pages, learn something new in an Instant! A short, fast, focused guide delivering immediate results, utilize multiple cursors to edit your text in many locations at the same time, etc. For more information please visit : http://www.packtpub.com/sublime-text-starter/book I’m contacting you because I’m aware that you share good knowledge in the subject this book covers, and so believe that your comments would be important for both consumers and readers alike. For this, I’d be glad to offer you a digital copy of the book.
About a week after I replied I received a second email that contained the details on an account which had been created for me so I could download a PDF copy of the book. I’ve read through it a couple of times now and my review of it follows.
Instant Sublime Text Starter
At 46 pages, Instant Sublime Text Starter is short and to the point. It covers Sublime Text 2 installation (on Windows, Linux, or Macintosh operating systems), walks you through very basic steps on quickly creating and editing a document, and rounds out with a very brief look at some Sublime Text features.
If you were brand new to text editors and wanted something to get you started quickly Instant Sublime Text Starter might be an acceptable resource. Unfortunately there’s no depth to any of the material covered. It really is just a starter.
For anyone with any experience at all setting up and configuring programming tools, the level of discussion in Instant Sublime Text Starter will be too basic. And the suggestion that you edit Preferences | Settings Default to enable Vintage mode rather than Preferences | Settings User is not a good idea. Changes made to Settings Default will be overlaid the next time you update Sublime. User configurations and settings should always be made in Preferences | Settings User.
There are many resources available to get you started in any new topic, and Sublime Text is no exception. For my money I’d recommend the tutsplus.comPerfect Workflow in Sublime Text 2 to any developer wanting to really explore Sublime Text. For non-technical users wanting just enough information to get started, you might consider Instant Sublime Text Starter.
I started by forking the Github findi project. There is a sample Heroku project as well, complete with instructions on using Heroku to host your tracking efforts. While I’m not using Heroku I did make use of the bootstrap.py and record_location.py scripts and requirements.txt file from the findi-heroku-example project.
Once I had cloned the fork to my laptop, I copied the contents of the bootstrap.py, record_location.py, and requirements.txt files to my local copy of the project. This way my fork is based on the findi project itself, and not the example Heroku one, but I have the additional files from the example project.
Next I tested findi against my iPhone. findi wrappers Apple’s Find My iPhone API and therefore is dependent upon your Apple ID. Once you instantiate a findi object using your Apple ID and Password, you can get a list of all the devices you are tracking. In my case that list contained 5 devices: my laptop, an original iPad, a brand-new iPad Mini, my iPhone, and my work iMac.
Plugging the index of my iPhone (3, in a zero-based list) into the API gave my my current latitude and longitude. Using copy and paste I was able to verify my location on Google Maps.
Modifying the Script for My Device List
The record_location.py script expects a device mapped to your Apple account.
record_location.py
123
"Fetches an iPhone location from the Apple API and creates a Location Object"
iphone=FindMyIPhone(APPLE_EMAIL,APPLE_PASSWORD)
iphone_location=iphone.locate()
Since I have 5 devices I changed the code slightly and hard-coded the index for my iPhone:
record_location.py
1234
"Fetches an iPhone location from the Apple API and creates a Location Object"
iDevices=FindMyIPhone(APPLE_EMAIL,APPLE_PASSWORD)
# my phone is the 4th device (index 3) in the list
iphone_location=iDevices.locate(device_num=3)
By default the script records the UTC time for each location.
record_location.py
12
date=Column(String,default=datetime.utcnow,
onupdate=datetime.utcnow)
I’d rather have the time for my timezone, so I changed the utcnow method to be today:
record_location.py
12
date=Column(String,default=datetime.today,
onupdate=datetime.today)
Finally, in order to execute record_location.py easily from cron, I added a hash-bang to the top of the file:
record_location.py
1
#!/usr/local/bin/python2.6
My server through WebFaction provides multiple Python versions, the python2.6 specifies the exact version I want.
Setting Up PostgreSQL and Cron
I used WebFaction’s control panel to create a new PostgreSQL database, along with a database userid and password. record_location.py expects the Apple Email, Apple Password, and database URL to be in environment variables called APPLE_EMAIL, APPLE_PASSWORD, and DATABASE_URL respectively. At the command prompt I exported these variables, filling in the appropriate values:
Running bootstrap.py with the exports in place created the table needed inside the PostgreSQL database.
Running the record_location.py script now resulted in a new row being inserted into the database.
Cron runs in its own environment and knows nothing about my exports, so I created a .cronvars file to house the required variables, so that I could source them, thereby making them available to the cron environment when the the script was executed. Here’s the line I added to my crontab:
Initially I set the cron job to run every few minutes so I could see some rows appear in the table and verify that everything was working. Once it was clear that it was working, I changed the time to be 0, or once an hour on the hour.
Fun and Profit
Now I have to wait a while to start collecting data from my phone’s location; which by and large is my location. Eventually I’ll use TileMill and MapBox to create a map. That will be the subject of a future posting.
zsh is a superset of the venerable Bash shell. It has first class functions, modular enhancements, comes pre-installed on Mac OS X, and offers fantastic tab completion. As a jump start to getting a working zsh environment in place, Matthew pointed us toward oh-my-zsh, a framework with tremendous community support. oh-my-zsh offers modular zsh plug-ins, Git repository information in your prompt, a customizable right-side prompt, themes, and more.
By cloning the oh-my-zsh project on Github, selecting one of the themes, and changing your default shell to zsh you can have a flexible and power new shell in a matter of minutes. With a little judicious Googling and some experimentation it’s easy to develop a shell environment that’s tuned to your style of working. Over time I built up my prompt (the most visible portion of the environment) to display interactive version control status information from Git, Mercurial (hg), or Subversion (svn) when the current directory was under version control. My right-prompt showed the current RVM managed Ruby and Pythonvirtual environment. I could also see at a glance what user I was, on which machine, and the current directory path. Oh, and all in vibrant colors.
Over time the features of zsh that I’ve come to rely upon the most are the tab completion and some of the directory movement commands. However, recently I had become dissatisfied with the delay when opening a new shell in a tab or window. A several second delay wasn’t unusual. In my efforts to pack as much information as possible into the prompt I created a resource intensive monster that was increasingly annoying. I began to question the need for dynamic svn repository information in the prompt when I rarely worked with Subversion any more.
Additionally, I had switched away from the main oh-my-zsh project to a fork created by Steve Losh. He added a function that exposed more status states for Git repositories. And I was using a Python script of his that exposed Mercurial repository information for the prompt. My prompt was capable of informing me of many things based on the current context, but the underlying structure had grown large and burdensome. Two weeks ago I decided to pare down my zsh setup, and in doing so I hoped to achieve two goals. One, I wanted to have a much better understanding of what was actually driving my shell’s environment. Two, I wanted to have a simpler, and hopefully quicker loading, setup.
Lobotomizing My oh-my-zsh theme
My first thoughts were to remove some of the less used information from my zsh prompt theme. I had added svn information since we use svn at work. However my role there shifted and I have no real need (at the moment) for Subversion reporting in my prompt.
It was the matter of a couple minutes work to comment out the Subversion related code from my theme file and source .zshrc. The subjective measure of my prompt’s loading time wasn’t much improved.
Next up I commented out the Mercurial aspects of the prompt. I stared out using hg a few years ago but, following the herd, I’ve moved all my projects to Git and Github. Again, my prompt didn’t really seem to be any faster.
Taking a new tack, I hunted around and found a completely new zsh theme I liked the general looks of called Fino. It had basic Git repository status information, RVM or rbenv Ruby information, and Python virtualenv reporting. With it in place in my .zshrc file the prompt was changed but I started getting error messages. zsh: command not found: rvm_ruby with every command issued.
Googling the message took me to a number of stackOverflow threads and some pages about Mac OS X’s path_helper. Something about the new theme wasn’t getting along with the rest of my zsh environment.
A Brief Digression into path_helper
path_helper examines the contents of /etc/paths.d and adds entries to your $PATH. The consensus seems to be that while it’s a good idea, it may not be implemented in the best fashion.
While I was reading all the pages I could find about path_helper, I wasn’t seeing the forest for the trees. RVM, and rbenv, are dependent upon their libraries being first in the PATH. If the PATH is altered after those key libraries are setup, the order may no longer be correct.
Frustrated by my lack of success in either altering my theme or incorporating the Fino theme, and not getting the clue the path_finder Google results were giving me, I reverted to my original theme and changed my primary text editor from TextMate to Sublime Text 2. When in doubt, go shave a yak.
Shaving the Sublime Text 2 Yak
I tend to collect open tabs in my browser. I usually have 30 or 40 open tabs and sometimes as many as 100. Periodically I scrub through them all and “do something” with at least some of them. Mentally stuck on the zsh: command not found error, I wandered through my open tabs and stopped on the nettuts plus Perfect Workflow in Sublime Text free course. Next thing you know I’ve dusted of my previous installed, but never really used, Sublime Text 2 application and started adding plug-ins and a color theme or two. I wasn’t solving my zsh theme issues, but I was using new and different tools to look at the reluctant code. When you can’t see the solution, change glasses, right?
With a newly configured and tweaked editor ready for use I returned to the original project.
Struggles with RVM
There are two Ruby environment managers: RVM and rbenv. I’ve used both in the past, although RVM has been my primary one for longer. The framework I use for my Websites is Octopress, which is Ruby-based. I initially installed RVM to setup and configure the required Ruby and Gems to get my site infrastructure working.
Since the error message I was getting seemed to be pointing a finger at RVM I decided to switch to rbenv. Rather than solve the problem, I thought, I’ll just switch environment managers. Easy as pie.
Rather than jeopardize my working-if-slow-loading environment I decided to use a different machine for my rbenv experiment. I have access to an older, but still serviceable aluminum MacBook Pro. I had recently formatted its hard drive and installed Linux Mint on it just to explore that distribution. I wiped the drive and installed Mountain Lion and rebuilt the machine to match my personal machine as closely as possible with one key difference: I setup rbenv and not RVM.
At this point, with a test bed that I could afford to be risky with, I stepped back from trying to get oh-my-zsh working and considered switching to the other zsh framework I had read about.
Looking at zshuery
zshuery is a much lighter-weight framework than oh-my-zsh. Based on the commit activity it isn’t nearly as frequently updated either. My concerns with it ran deeper than a seeming lack of support. Without digging into both oh-my-zsh and zshuery and comparing them at a nuts and bolts level I wouldn’t know what one had that the other didn’t. What would I gain with zshuery? What would I lose and have to recreate?
While starting out with oh-my-zsh was fantastic, it came with a hidden cost. Since I knew nothing about zsh prior to using the framework I had no way of knowing what was raw zsh and what was framework-added. To me, oh-my-zsh was zsh.
We Interrupt this Program for a Brief Word About Writing Sorts
In my college internal data structures course we wrote a sort. After a lecture discussion the ins and outs of the algorithm I wrote my very own bubble sort. The following lecture the professor showed us the JCL sort utility. At first I was upset that I spent all the time and effort to reinvent the sort wheel, but later I came to realize that I had a better understand and appreciation for sorts as a result of the exercise.
My zsh experience was the opposite of my sort experience. I started zsh with the polished, design-decisions-already-made-for-you solution. If I really wanted to get to the bottom of my zsh shell slowness I would need to build my own environment, eschewing frameworks.
ze-best-zsh-config
Github is a wonderful place as people store all sorts of things there, open to the public. In my sifting of Google zsh search results I stumbled onto a repository cheekily named ze-best-zsh-config. At first glance it looked well laid out. The various aspects of the configuration, options, exports, the prompt, history, aliases, and functions, were all isolated in their own .zsh files, and the resulting components brought together in the .zshrc file.
Here was a starting point for my own, hand-rolled zsh environment. I cloned the repository and started working through the .zsh files it contained line-by-line to understand them.
Switching to rbenv
Installing and using rbenv isn’t any harder than installing and using RVM. Reflecting the current active Ruby in my shell’s right-prompt (RPROMPT) proved to be one of the hardest parts of this project.
I liked the code from the Fino theme for interrogating the host machine for either RVM or rbenv and then determining what Ruby was active. Copying that code to my new prompt.zsh file didn’t work however. The right-prompt either showed nothing at all, or the line of code that should have resolved to the Ruby name. After an evening of Googling and trial and error I finally posted a question on stackOverflow. The next morning I not only had a working answer, I had an explanation of how it worked. I love the Internet.
setopts, Exports, Aliases, Functions, Colors, Completions, and History
With my prompt sorted it was time to understand all the configuration options available to me, and setup my environment. Working from the setops included in ze-best-zsh-config, I looked everything up. Some I kept, others I changed, a few I dropped. Next I read through the options defined in zshuery.
I performed similar examinations of the colors, completions, history, exports, aliases, and functions .zsh files. I merged my existing functions and aliases into the starter files, and incorporated some more from zshuery.
From zshuery I liberated the idea of testing the host machine’s operating system (uname) and setting an attribute. This allows me to have options that are OS specific.
More path_helper Adventures
During the due diligence process I managed to break the right-prompt. Suddenly the zsh: command not found error was back. Somewhere along the line I had managed to break the path. After much searching and reading I finally created a .zshenv file and copied the code necessary to run path_helper there. I then altered this code to completely clear the path, ensuring that I had no unexpected cruft there. This article about path_helper was instrumental in my getting the problem solved.
I also placed the path and shim setup for rbenv into the .zshenv file. With this file in place the zsh: command not found error disappeared. Hopefully for good.
Putting it All Together
My new .zshrc file is just a list of .zsh files that get sourced.
.zshrc
123456789101112
source ~/.zsh/checks.zsh
source ~/.zsh/colors.zsh
source ~/.zsh/setopt.zsh
source ~/.zsh/exports.zsh
source ~/.zsh/prompt.zsh
source ~/.zsh/completion.zsh
source ~/.zsh/aliases.zsh
source ~/.zsh/bindkeys.zsh
source ~/.zsh/functions.zsh
source ~/.zsh/history.zsh
source ~/.zsh/zsh_hooks.zsh
source${HOME}/.dotfiles/z/z.sh
And those files each contain a portion of the overall configuration. I suppose they could all be combined into one large file, but I like breaking them up into logically related components.
.zshenv
Here is where we override path_helper by calling it again ourselves. The PATH is cleared first and then rebuilt. The result is far less duplication of directories. rbenv is also setup here.
.zshenv
1234567891011121314
# Mac OS X uses path_helper and /etc/paths.d to preload PATH, clear it out first
if[ -x /usr/libexec/path_helper ]; then
PATH=''
eval`/usr/libexec/path_helper -s`
fi
# if rbenv is present, configure it for use
if which rbenv &> /dev/null; then
# Put the rbenv entry at the front of the line
export PATH="$HOME/.rbenv/bin:$PATH"
# enable shims and auto-completion
eval"$(rbenv init -)"
fi
checks.zsh
These tests allow me to later isolate exports, or setopt statement based on the host machine’s operating system.
checks.zsh
1234567891011121314151617181920
# checks (stolen from zshuery)
if[[$(uname)='Linux']]; then
IS_LINUX=1
fi
if[[$(uname)='Darwin']]; then
IS_MAC=1
fi
if[[ -x `which brew`]]; then
HAS_BREW=1
fi
if[[ -x `which apt-get`]]; then
HAS_APT=1
fi
if[[ -x `which yum`]]; then
HAS_YUM=1
fi
colors.zsh
A colorful shell is a happy shell. But the escaped codes are arcane and miserable to work with. Let’s give them some readable names.
colors.zsh
12345678910111213141516171819202122
autoload colors; colors
# The variables are wrapped in %{%}. This should be the case for every
# variable that does not contain space.
for COLOR in RED GREEN YELLOW BLUE MAGENTA CYAN BLACK WHITE; do
The visible tip of the zsh environment iceberg. Lots going on here.
The Python virtual environment, if one is active, is captured for display in the right-prompt.
The prompt character displayed is normally a $ or maybe a >. I’m using the symbols Steve Losh had in his extravagant zsh prompt
box_name is a clever way to show your preferred name for the machine you are on. Just create a ~/.box-name file and put the name you want there. Or, on Mac OS X, use the sudo scutil --set HostName <your-name-here> command.
A variety of variables are set up for Git repository status reporting, and then there are some functions to interrogate Git. This information is shown in the main prompt.
The current Ruby active is determined by interrogating either RVM or rbenv, which ever is present on the machine. This function, _update_ruby_version(), has been added to the chpwd_functions array like so: chpwd_functions+=(_update_ruby_version). This means it is only executed when the directory changes.
Finally there is a function to get the name of the current working directory.
The primary prompt shows the username, box name, current working directory, and git branch and status (if present). The prompt is preceded by a blank line, and places the prompt character on a line of its own. This makes reading the console far easier.
zsh provides an error prompt, which I’m using to spell correct commands. The export SPROMPT line handles this.
Lastly the troublesome right-prompt or RPROMPT. Here the Python virtual environment information and active Ruby information is displayed. One of the setops defined above, setopt transient_rprompt causes the RPROMPT to only appear on the current, most recent, prompt. I’m not sure yet if I like this, but it does make the console seem less cluttered.
I’ve had some of these aliases for as long as I’ve been working on *nix-based machines. They are as much a part of my muscle memory as tying my shoe or combing my hair. Since zsh tries to spell correct commands, the nocorrect section is at the top. Here is where you put commands that you don’t want spell checked every time they are used.
alias ql='qlmanage -p 2>/dev/null'# OS X Quick Look
alias oo='open .'# open current directory in OS X Finder
alias'today=calendar -A 0 -f /usr/share/calendar/calendar.mark | sort'
alias'mailsize=du -hs ~/Library/mail'
alias'smart=diskutil info disk0 | grep SMART'# display SMART status of hard drive
# Hall of the Mountain King
alias cello='say -v cellos "di di di di di di di di di di di di di di di di di di di di di di di di di di"'
# alias to show all Mac App store apps
alias apps='mdfind "kMDItemAppStoreHasReceipt=1"'
# reset Address Book permissions in Mountain Lion (and later presumably)
alias resetaddressbook='tccutil reset AddressBook'
# refresh brew by upgrading all outdated casks
alias refreshbrew='brew outdated | while read cask; do brew upgrade $cask; done'
# rebuild Launch Services to remove duplicate entries on Open With menu
alias rebuildopenwith='/System/Library/Frameworks/CoreServices.framework/Frameworks/LaunchServices.fram ework/Support/lsregister -kill -r -domain local -domain system -domain user'
bindkey -v # Default to standard vi bindings, regardless of editor string
functions.zsh
Some of these are my own creation, others I’ve picked up along the way. The most recent addition, path() displays your current PATH beautifully. Immensely helpful when sorting out path issues.
The variables control how the command history is managed.
history.zsh
1234
# HISTORY
HISTSIZE=10000
SAVEHIST=9000
HISTFILE=~/.zsh_history
zsh_hooks.zsh
This file controls the use of the precmd, preexec and postcmd features. I’m not entirely sure I understand all there is to know about this. It’s on the list to investigate more thoroughly.
zsh_hooks.zsh
1234567891011121314151617181920
function precmd {
# vcs_info
# Put the string "hostname::/full/directory/path" in the title bar:
z tracks your most used directories based on ‘frequency’. By typing z and part of a directory name I can quickly jump to that part of the file system. Obviously the longer you have it installed the better it performs. I highly recommend it.
Looking Forward
My original RVM + oh-my-zsh configuration had the path and setup for RVM contained in the .zlogin file. The new rbenv + zsh configuration has the rbenv setup in .zshenv. I need to read more on these two files and decide which ought to be used.
I need to explore the subject of bindkeys more to fully understand what they are and how I can benefit from them. I also need to learn about precmd, preexec, and postexec. There use in my setup was copied from ze-best-zsh-config. And zsh_hooks.
My testbed machine has 100 GB of free space on it’s hard drive that I am planning on using to install Linux Mint. Once that OS is setup and running I want to use my dotfiles repository, including the new zsh configuration, there. As I get things setup and working under Linux I’m sure there will be Linux-specific tweaks to add to the configuration.
In the end I’m not sure I’ve made my prompt load any faster. I certainly understand the processes and configuration behind it far better than before. I haven’t taken the step of removing all the entires from /etc/paths.d and placing them directly into my $PATH. This feels like something that would need constant minding and I’m not ready for that yet.
I’ll need to live with this setup for a while to discover things I’ve lost by leaving oh-my-zsh. Hopefully nothing to drastic or hard to configure myself. It’s been an interesting couple of weeks sorting this out. I have a greater appreciation for my shell now, and a greater understanding of what makes it tick.