"Beautiful as poetry; ludicrous as science."


The realm of the mind is entirely fantasy. Fantasy in the typical definition is something of a historical time coming out of the dark ages with swords and knights, often with some element of magic or otherworldly realm, but I mean fantasy in the “not reality” aspect.

Reality is what is here and now, or what has been as known by us now, or what will be as predicted by us now. There is a “cone of uncertainty” extending to the past and future in which we may traverse, but outside of that cone lies fantasy.

When it comes to literature, imagination, and storytelling there is no “cone of certainty.” That which is fiction is by definition freed of the cone, and much of what is related as “history” is also separated. The future may lie in the cone but until we reach it, it is fantasy. Does it do any good to debate this fine line?

Time in stories progresses only as the writer would have it. The reader reads at the pace the writer writes, having no control over the flow of time. Similarly characters in the stories can utter no sentences and think no thoughts other than that which the writer writes, perform no actions other than what the writer writes, and have no material lives outside of the story. The minds of the reader may capture the essence of the story and project the possibilities in all manner of directions, but that story is in the mind of the reader alone.

Elements woven throughout the writing may not relate much to reality, or may not at all. The imagination of a writer is their greatest asset. Their “intellectual property” is entirely immaterial yet our legal system works to protect it just as it protects material products. And yet they profit by way of “piracy of the mind” in every single reader captivated by those fictional elements.

When it comes to “cone-possible” stories set in baroque, westerns, medieval, or barbaric stone-age settings but entirely made-up, one fiction is as fictional as the rest. To relate to the reader is the ultimate test of how well the creation comes alive. Similarly, rocket ships, elves, elemental control, fantastical deities, other worlds, and perhaps even other physical models that are “cone-impossible” are in their own realm and degree of fiction, but are fiction just the same. Out of the pen of a writer springs a story, and if that story relates to the reader and evokes a connection with the sprit of imagination, they are not far removed from any other fiction.

The writer is the crafter of dreams, casting those rough-hewn imaginings of every reader into finely-wrought works fit for carrying with them for the rest of their life, vicariously living beyond any mortal possibility.


I struggled for years to keep up with my inbox and none of the endless variations of GTD helped. When I found Yesterbox it immediately clicked and now I easily keep up. I am replicating this post here in case the original ever vanishes (again).

One final note: To do this in GMail there is no “yesterday” filter, so I use in:inbox older_than:16h and the Multiple Inboxes lab. In FastMail (my prefered mail provider) I use before:today as a saved search. Outlook is described below.

Content © Tony Hsieh

For over a decade now, my email inbox has been my to do list… so the longer it gets, the more stressed I feel. But the problem is that it’s a never-ending treadmill, there’s never a sense of completion, and it’s virtually impossible to get to the elusive goal of “inbox zero”; because as soon as I start sending emails, replies start coming back to me. And even if I do get to inbox zero (which has happened less than 10 times in the past decade for me), it lasts only a few hours.

In 2012, I felt like my email had gotten out of control. I felt like it was a never-ending treadmill, and a lot of important emails I would actually end up never getting to because they would take a long time to respond to and I would just end up procrastinating… and several months later, they were still unanswered.

At the end of 2012, I started experimenting with an email management technique which has actually worked out surprisingly well for me, and I’d love for more people to try it out and share it with others. I call my technique “Yesterbox”, because the basic premise is that each day your to do list is yesterday’s inbox instead of today’s inbox.

Here are the details behind the Yesterbox technique:

  1. Your “to do” list each day is simply yesterday’s email inbox (hence, “Yesterbox”). The great thing about this is when you get up in the morning, you know exactly how many emails you have to get through, there’s a sense of progress as you process each email from yesterday and remove it from your inbox, and there’s actually a point when you have zero emails left to process from yesterday.There is actually a sense of completion when you’re done, which is amazing. I would say that on half the days, I’m actually completely done with all my email obligations by NOON, which has been an incredibly freeing feeling. Even though my responses to most emails are not the same day, I actually end up being MORE responsive than I have been in the past, because most people will get a response the day after (as opposed to a week after, a month after, or several months after which used to happen all the time because I would always procrastinate on the hard emails).
  2. If it can wait 48 hours without causing harm, then you are not allowed to respond to any emails that come in today, even if it’s a simple one-word reply. This is the part that really takes a lot of discipline for the first week or so, because it is really really tempting to respond to emails that come in. Basically, you need to psychologically train yourself to not worry about emails that are coming in… don’t think of them as being in your inbox, that’s tomorrow’s to do list… unless it can’t wait 48 hours, they are not your problem today. Your focus today is just on clearing out yesterday’s inbox.
  3. When processing yesterday’s inbox, you must process 10 of yesterday’s emails before you’re allowed to look at any emails that are coming in today. After you’ve processed 10 (meaning removed them from yesterday’s inbox either by replying, filing, deleting, or calendaring them (more on that below), then your “reward” is that you get to read the new emails that have come in. (Generally, I’ve found that it takes me about 30 minutes to process 10 emails.)We’re all guilty of procrastinating and looking for the easy emails to respond to first. By forcing yourself to do 10 at a time of yesterday’s emails (and not allowing yourself to read any new emails that come in today until you do 10 from yesterday), it’s a lot easier to power through the annoying or harder ones… and as you make progress towards the finish line of zero emails from yesterday, you see the finish line getting closer and closer… and when you’re done processing all of yesterday’s emails, you’re done for the day.If you’re using Outlook, one tip to avoid cheating and reading today’s emails prematurely is to simply collapse your “Today” group of emails by clicking on the arrow in the header (to the left of the word “TODAY”).
  4. Calendaring: For any email from yesterday that takes more than 10 minutes to respond, or requires additional research, etc., you should simply file it away into a folder and then schedule a time on your calendar in the future to respond, as if it were a meeting. On my calendar appointments, I just put the name of the folder I filed it away in, as well as the subject line of the email I filed away.So if you have an email that will take an hour to respond to, just set it up as a 1-hour meeting at some point in the future. This will make sure that you always have enough time to respond to that email in the future. The act of filing that email away in a folder means it’s out of your inbox so it’s not stressing you out anymore… You know it will be responded to properly because you’ve set an appointment for it.
  5. You also need to set a recurring appointment to go through yesterday’s inbox every day. For me, getting through the previous day’s email takes about 3 hours, so I simply schedule a 3-hour meeting at the beginning of each day for Yesterbox. My assistant knows that if I need to take a morning meeting, that the email time can’t go away — it needs to be rescheduled for later in the day. Or on the rare occasion there isn’t enough time in the day, then my assistant knows that there needs to be makeup time scheduled the next day for time lost on the current day.
  6. When in your “reward” phase of reading the latest emails from today, you’re only allowed to do the following with today’s emails: delete, file, or forward. You are not allowed to reply unless it can’t wait 48 hours. The one exception to that rule is if there’s an email chain from yesterday but the chain is continuing through today, it’s okay to respond to one of today’s emails in that chain if doing so means you get to delete or file yesterday’s email in that chain (in other words, it’s allowing you to make progress on yesterday’s inbox).
  7. If you need to refer to an email later (for example, to follow up and make sure something didn’t slip through the cracks when you asked someone else to follow up), schedule a meeting on your calendar and file the email into another folder, with a reminder in the calendar appointment to refer back to that folder and what the name of the folder is.
  8. If you fall behind and have emails that are older than yesterday’s inbox (yes, it still happens), schedule additional time on your calendar to catch up to emails older than yesterday’s inbox. However, each day you should start with yesterday’s inbox as your “to do” list FIRST… this means you get a fresh start each morning and can be done with yesterday’s inbox by noon just like you would be if you hadn’t fallen behind.If you go on vacation and aren’t planning on keeping up with emails, then be sure to schedule enough email catchup time in your calendar for when you get back from vacation.
  9. For emails that can wait (such as videos, non-urgent articles, etc.) and have no real deadline, send those emails to another email address (such as your personal email address — for me, I send them to my email address) and just go through that other email inbox when you’re trying to kill time, like on a plane, at the gym, waiting in line, etc. When people send me a video link, I just respond with something along the lines of “Thanks! I’ve put it on my treadmill video playlist!”There’s also a product called Pocket that is a good “save to read later” app and browser plugin.
  10. Put emails that are notes into Evernote and remove them from your inbox.

So I encourage you to try out the Yesterbox technique and share it with friends. For me, it took about a week to psychologically get used to it, and I feel a lot less stressed about my email nowadays.

(The other great thing about this is that it actually has beneficial network effects… the more people that adopt the Yesterbox technique, the more in control of their inbox everyone will feel!)

-Tony Hsieh

Efficient Editing With Vim

Translations of this article are available in German (Effiziente Textbearbeitung mit Vim), French (L’édition efficace avec vim), Italian (Vim e Gvim: usarli in modo efficiente, and Chinese (高效使用vim). Content © J. McPherson

“To me, vi is Zen.
To use vi is to practice zen.
Every command is a koan.
Profound to the user,
unintelligible to the uninitiated.
You discover truth every time you use it.”

This tutorial assumes a basic knowledge of vim — insert mode, command mode, loading and saving files, etc. It is intended to help vi novices develop their skills so that they can use vi efficiently.

In this tutorial, <C-X> means Ctrl-X — that is, hold down the Ctrl key and press X. You can get help on most of the commands used here by typing :help command in vim, where command is what you need help on.

Moving efficiently

Stay out of insert mode

In general, you want to spend as little of your time in vim’s insert mode as possible, because in that mode it acts like a dumb editor. This is why most vim novices spend so much time in insert mode — it makes vim easy to use. But vim’s real power lies in command mode! You’ll find that the better you know vim, the less time you will spend in insert mode.

Use h, j, k, and l

The first step to efficient editing in vim is to wean yourself from the arrow keys. One of the the advantages of vim’s modal design is that you do not need to constantly move your hands back and forth between the arrow keys and the letter keys; when you are in command mode, the letters h, j, k and l correspond to the directions left, down, up, and right, respectively. It takes some practice to get used to, but you will notice the speed difference once you’re used to it.

When you are editing e-mail or other paragraph-formatted text, you might notice that the direction keys skip more lines than you expect. This is because your paragraphs appear as one long line to vim. Type g before h, j, k or l to move by screen lines instead of virtual lines.

Use motions to move the cursor in the current line

Most editors have only simple commands for moving the cursor (left, up, right, down, to beginning/end of line, etc). vim has very advanced commands for moving the cursor; these commands are referred to as motions. When the cursor moves from one point in the text to another, the text between the points (and including the points themselves) is considered to be “moved over.” (This will be important later.)

Here are a few of the more useful motions:

fx Move the cursor forward to the next occurance of the character x on the current line (obviously, x can be any character you like). This is an extremely useful command. You can type ; to repeat the last f command you gave.
tx Same as above, but moves the cursor to right before the character, not all the way to it. (It’s very useful, really.)
Fx Move the cursor backward to the next occurance of the character x on the current line.
w Move the cursor forward by a word.
b Move the cursor backward by a word.
0 Move the cursor to the beginning of the current line.
^ Move the cursor to the first character on the current line.
$ Move the cursor to the end of the line
) Move the cursor forward to the next sentence. (Useful when editing e-mail or text documents.)
( Move the cursor backward by a sentence.

Move efficiently through the file

vim has many commands that can send you to where you want to go in your file — there’s rarely a need to scroll manually through it. The below keystrokes are not technically motions, since they move around in the file instead of in a particular line.

<C-F> Move the cursor forward by a screenful of text
<C-B> Move the cursor backward by a screenful of text
G Move the cursor to the end of the file
numG Move the cursor line num. (For instance, 10G moves to line 10.)
gg Move the cursor to the beginning of the file
H Move the cursor to the top of the screen.
M Move the cursor to the middle of the screen.
L Move the cursor to the bottom of the screen.
* Read the string under the cursor and go to the next place it appears. (For instance, if your cursor was somewhere on the word “bob,” the cursor would move to the next occurance of “bob” in your file.)
# Same as above, except it moves the cursor to the previous occurance.
/text Starting from the cursor, find the next occurance of the string text and go to it. You will need to press Enter to execute the search. To re-execute your last search, type n (for next occurance).
?text Same as /, but searches in the opposite direction.
ma Make a bookmark named a at the current cursor position. A bookmark can be named any lowercase letter. You can’t see the bookmark, but it’s there!
`a Go to bookmark a. Important: that’s a backtick, not a single quote. The backtick is located to the left of the 1 on most keyboards.
`. Go to the line that you last edited. This is very useful! If you need to scroll through the file to look something up, you can go back to where you were without bookmarking it by using the `. command.

Typing efficiently

Use keyword completion

vim has a very nice keyword completion system. This means that you can type part of a long word, press a key, and have vim finish the word for you. For instance, if you have a variable called iAmALongAndAwkwardVarName somewhere in your code, you probably don’t want to type the whole thing in every time you use it.

To use keyword completion, just type the first few letters of the string (e.g. iAmAL) and press <C-N> (that means hold down Ctrl and type N) or <C-P>. If vim doesn’t give you the word you want at first, keep trying — vim will cycle through all completions it can find.

Enter insert mode intelligently

Most users new to vim get into insert mode by typing i. This works, but it’s often pretty inefficient, since vi has a host of commands that leave the editor in insert mode. Here are some of the more popular ones:

i Insert text to the left of the current character.
I Insert text at the beginning of the current line.
a Insert text to the right of the current character.
A Insert text at the end of the current line.
o Create a new line under the current one and insert text there.
O Create a new line above the current one and insert text there.
c{motion} Delete (change) the text moved over by {motion} and insert text to replace it. For instance, c$ would delete the text from the cursor to the end of the line and enter insert mode. ct! would delete the text from the cursor up to (but not including) the next exclamation mark and enter insert mode. The deleted text is copied to the clipboard and can be pasted.
d{motion} Delete the text moved over by {motion} — same as c{motion}, but doesn’t enter insert mode.

Moving blocks of text efficiently

Use visual selections and the appropriate selection mode

Unlike the original vi, vim allows you to highlight text and perform operations on it. There are three main visual selection modes (that is, text highlighting modes). These modes are as follows:

v Characterwise selection mode. This is the selection mode that most people are used to, so practice with it before trying the others.
V Linewise selection mode. Whole lines are always selected. This is better than characterwise mode when you want to copy or move a group of lines.
<C-V> Blockwise selection mode. Extremely powerful and available in very few other editors. You can select a rectangular block and any text inside that block will be highlighted.

All the usual cusor movement keys apply — so, for instance, vwww would go into visual selection mode and highlight the next three words. Vjj would go into linewise visual selection mode and highlight the current line and the two lines below it.

Cutting and copying from visual selections

Once you have a highlighted selection, you probably want to do something with it. Some of the more useful commands you can give when an area of text is highlighted:

d Cut (delete) the highlighted text and put it into the clipboard.
y Copy (or yank, which is vim-ese for “copy”) the highlighted text into the clipboard.
c Cut the highlighted text into the clipboard. This is just like d, except it leaves the editor in insert mode.

Cutting and copying from non-visual selections

If you know exactly what you want to copy or cut, you can do it without entering visual mode. This saves time.

d{motion} Cut the text moved over by {motion} to the clipboard. For instance, dw would cut a word and dfS would cut from the cursor up to and including the next capital S on the current line of text.
y{motion} Copy the text moved over by {motion}.
c{motion} Cut the text moved over by {motion} and leave the editor in insert mode.
dd Cut the current line.
yy Copy the current line.
cc Cut the current line and leave the editor in insert mode.
D Cut from the cursor to the end of the current line.
Y Yank the whole line, just like yy. (Yes, it’s inconsistent! You can use y$ to do what you would expect Y to do.)
C Cut from the cursor to the end of the current line and leave the editor in insert mode.
x Cut the current character. (This is sort of like a command-mode backspace.)
s Cut the current character and leave the editor in insert mode.


Pasting is easy. Put the cursor where you want the pasted text and type p.

Using multiple clipboards

Most editors have a single clipboard. vim has many more; clipboards in vim are called registers. You can list all the currently defined registers and their contents by typing :reg. Typically, you’ll be using the lowercase letter registers; the others are used for various internal vim purposes and are only occasionally helpful.

To use a specific register for a copy or paste operation, simply type "a before the command for the operation, where a is the register you want to use.

For example, to copy the current line into register k, you could type "kyy. (You could also type V"ky. Why would that work?). That line would stay in register k until you specifically copied something else into register k. You would then use "kp to paste the text from register k.

Avoiding repetition

The amazing . command

In vi, typing . (a period) will repeat the last command you gave. For instance, if your last command was dw (delete word), vi will delete another word.

Using counts

Counts are one of the most powerful and time-saving features of vim. Any command can be preceded by a number. The number will tell vim how many times to execute the command. Here are a few examples:

3j will move the cursor down three lines.

10dd will delete ten lines.

y3f" will yank (copy) text from the cursor to the third quotation mark after the cursor on the current line. Counts are useful to extend the range of a motion in this manner.

Recording macros

Occasionally, you’ll find yourself doing the same thing over and over to blocks of text in your document. vim will let you record an ad-hoc macro to perform the operation.

qregister Start macro recording into the named register. For instance, qa starts recording and puts the macro into register a.
q End recording.
@register Replay the macro stored in the named register. For instance, @a replays the macro in register a.

Keep in mind that macros just record your keystrokes and play them back; they are not magic. Recording macros is almost an art form because there are so many commands that accomplish a given task in vim, and you must carefully select the commands you use while your macro is recording so that they will work in all the places you plan to execute the macro.

Writing code in vim

vim is an excellent editor for source code because it has many features that are specifically designed to help programmers. Here are a few of the more handy ones:

]p Just like p, but it automatically adjusts the indent level of the pasted code to match that of the code you paste into. Try it!
% Putting the cursor on a brace, bracket, or parenthesis and pressing % will send the cursor to the matching brace, bracket, or parenthese. Great for fixing parse problems related to heavily nested blocks of code or logic.
>> Indent the highlighted code. (See the earlier section about efficient text selection. If no text is selected, the current line is indented.)
<< Like >>, but un-indents.
gd Go to the definition (or declaration) of the function or variable under the cursor.
K Go to the man page for the word currently under the cursor. (For instance, if your cursor is currently over the word sleep, you will see the man page for sleep displayed.)

Sail Away Selah’s Way

Sorry for my absence. I’m sailing to Australia at the moment.

Scrobble to with Pianobar

Pianobar is an excellent command-line Pandora client. It has support for calling external commands when songs play, pause, skip, et cetera via the event_command directive. With this, we can add a little scrobbling script and get our listening tracks sent to

First, cd to ~/.config/pianobar (or mkdir if it doesn’t exist) and paste in as, and chmod +x it. You’ll have to open and add your API key (get one from and username/password.

Next, go to pylast and get and put it in the same directoy as

Finally, open or create ~/.config/pianobar/config and put in these lines:

user =
password = somethinglong
event_command = /Users/username/.config/pianobar/

Bonus: If you’re a Pandora One subscriber, you can get the high-quality stream by adding the audio_format = mp3-hifi directive.

(Note: Due to shortcomings in pianobar, your password can’t have funny characters like & in it.)

When you start pianobar, it should start showing up on after the first song finishes. If there are problems then pianobar should print them to stderr.

Edit 2011-06-02: The gist has been updated to support Now Playing. Update your with the new version and pianobar should automatically start updating with Now Playing.

Puppet bootstrap

When starting a brand-new puppet environment, this is the procedure I usually follow to get a client/server bootstrap. First get puppet installed on two boxes, one will be a master and one (or both) will be clients.

(Note: You need some kind of name-resolution infrastructure, either via DNS or /etc/hosts. Puppet clients by default try to contact your master via the short name puppet then the long name

To start, do the following (I’m assuming Puppet 2.6 commands. For 0.25 use puppetd for puppet agent and puppetmasterd for puppet master):

  • On the master: touch /etc/puppet/manifests/site.pp and puppet master --no-daemonize --verbose to watch for connections.
  • On the client: puppet agent --test You should see it generate and submit a cert to the master to be signed.
  • On the master: puppet cert --list to get the list, then puppet cert --sign <certname> to sign it.
  • On the client: puppet agent --test and it should get it’s signed cert, then a catalog from the master if you have a node definition for it.

If that messes up and you want to start over:

  • On the master: puppet cert --clean <certname> to clean the client’s cert.
  • On the agent: puppet agent --configprint ssldir then rm -rf that dir to remove its cert.

Once server<->client is working fine fine, ^C the puppet master and run:

  • On the master: service puppetmaster start
  • On the agent: service puppet start

Now you should be able to put modules in /etc/puppet/modules and node definitions in /etc/puppet/manifests/site.pp and the master will stat these every 2 seconds for changes. You can wait for the client to automatically contact the master for its catalog, or run puppet agent --test to see immediate results.

GTD Gmail Filter Tricks

One of my favorite blog posts of all time on Gmail GTD techniques is this one by Neil Dixon (Edit: Link is dead. Use this blog post instead). Using this technique means that if I want to manage a todo list in combination with my email GTD workflow, I have to check two places to see my task list (even if I’m using the task list built-in to Gmail). How can I combine my email GTD with my todo GTD into one place?

A quick tip about a gmail feature that is not well known. You can append +anything to the end of your username for any Gmail or Google Apps domain and it will still be sent to you. For example, or can be turned into or

To integrate my Gmail GTD workflow with an email-driven todo list, I should theoretically be able to have any single email sent “from me to me and only me” be archived and labeled @action. Gmail filters don’t currently have a way to filter based on “to me and only me,” so I improvised.

Create an email filter for “” (or whatever) to auto-archive and apply your @action label (and optionally a “Todo” label via a second filter), and send an email to this address with your one-line todo sentence in the email subject line. Thereafter, when composing an email you should be able to type “todo” into the To: line and hit <tab> and have it complete for your Todo list.

Protip: If you have keyboard shortcuts enabled and are viewing your @action emails, you can use ‘y’ to remove the @action label without removing the Todo label, essentially marking it “complete.”

Fullscreen Cocoa Emacs on OS X 10.6

The age old battle of editors rages on, but I have a feeling that it’s largely due to misunderstandings of purpose and ignorance of the opposing party. I have been a vi/vim user for 10+ years and found myself strongly advocating vim’s qualities of being lighter and more prevalence than emacs without having so much of an idea of how to quit emacs other than with pkill. Then I found myself with 3 months of free evenings and a slow-to-nonexistent internet connection and decided to fill some of that time and try emacs.

Long story short, I really like emacs for some tasks, and I really like vim for others. I love hacking on my .emacsrc but had been mostly constrained to running it in the terminal over ssh connections until I got a Mac. Now Macs are funny in that they are very GUI-gooey, but they manage to pull it off in a way that doesn’t make me, a hardcore terminal-only tiling-window-manager user, want to take a hammer to it.

Subsequently, I have been using the gui version of Emacs more and more, and it’s really something special on OS X. One feature I feel it’s lacking is fullscreen support. When working with vim, I toggle to fullscreen terminals when I really want to focus, so Emacs should allow me to do the same thing.

Shamelessly adapted from citizen428’s guide, guide, here is the step-by-step way to get fullscreen support written by typester on OS X vanilla emacs without having to rely on someone else’s compiled

# Get the official Emacs repo:
git clone git://

# Add typester as a remote and fetch his branches
git remote add typester git://
git fetch typester

# From a3585f6c2a to typester/feature/fullscreen are the 14
# commits we want to apply to our tree. Create a patch and apply to
# HEAD for the most cutting-edge Emacs
git checkout origin/master
git diff a3585f6c2a typester/feature/fullscreen | patch -p1

# Create a commit so you can just maintain your git tree for later
git commit -a -m "Typester's fullscreen patch" && git clean -d -f

# Alternatively, you could cherry pick all of typester's commits
# and not have to commit anything.
git cherry-pick 329d3eeab6e1997eed97e1fe40e5489a4c68edae \
                592a51bc2938e7c40a3c60b5a5301ea1510a0e74 \
                b9ff1ae683cf453da0415f5c83e329bbff35b9fa \
                000208df01f5c3af7d6f584304bc1a898701f87b \
                d8cf14d0243e5046f77051d05af31af77125d583 \
                df1e25370854fc04e4c217c214e9c02084c1ddae \
                41a9a1d946061c87ab6a6faf484a5b2e5812229f \
                c586de33d8e9ed6c94887526e9891de1788ba3f8 \
                663de471ea537083a86832c46984eab08407be90 \
                d1e183b01bd9f4608203aec5ae06518c37932a98 \
                b549c85507a1f52230c16ace217fe4e66308fc97 \
                5f2a5f555f475d570e6db2ffea4b259f0a90c302 \
                94512b4fd984146a62cde7d9c925058d0ebd0be3 \

# Done with typester's remote
git remote rm typester

# build emacs
./configure --with-ns
make && make install
mv nextstep/ /Applications/

# Later, to update emacs and keep fullscreen just do:
git pull origin master

I then bound “M-RET” to ns-toggle-fullscreen in my .emacsrc.

Suppress iTunes invocation on Pause/Play key

On my Macbook I have the F1-12 keys accessible under the Fn key, and instead by default they have various actions such as changing the volume or brightness, activating exposé, or other various functions. F7-F9 are shortcut keys for Next Track, Play/Pause, and Previous Track for music or other media.

When I got my mac I knew I didn’t want iTunes for various reasons, not the least of which is that it can’t play flac. I’m still looking for a good alternative for heavy usage of listening to my own music, but between‘s app and Pandora‘s awesome console program called pianobar (you can `port install pianobar`, I’ve only been listening to my own music about 50% of the time.

The other 50% of the time I’ve been using VLC, and it works out of the box with the keyboard media shortcuts! Except for one hitch… any time I press the Play/Pause button OS X tries to start iTunes, and there are more than one angry threads about Apple turning a deaf ear to making this configurable/disabled short of deleting iTunes. But there is a hack if you want both iTunes and VLC to co-exist.

Essentially I rename the iTunes binary and replace the original with a small script that first checks if VLC is running, and if not then launches iTunes. Just paste this into Terminal:

cd /Applications/
sudo mv iTunes iTunesX
sudo cat > iTunes << EOF
#!/usr/bin/env python
import sys, os, subprocess
launch = True
blocker = ""
apps = ["Spotify", "Songbird", "VLC"] # Add more blocking programs here
ps = subprocess.Popen("/bin/ps -x", shell=True, stdout=subprocess.PIPE)
for line in"\n"):
    for app in apps:
        if app in line:
            launch = False
            blocker = app
if launch :
    os.spawnvp(os.P_WAIT, '/Applications/', sys.argv)
else :
    print "Not launching iTunes while %s is running." % blocker
sudo chown root:admin iTunes #To match the perms of the other iTunes files
sudo chmod 775 iTunes

If you want to "reset" your iTunes, you can paste this:

cd /Applications/
sudo mv iTunesX iTunes

Dynamic Git-branch Puppet Environments

When working with puppet, eventually you’ll arrive at any one of several conclusions; you have a mass of code and want to refactor it, you have a cool idea that you want to prototype, or you want to add some code but don’t want to push it to production until it’s done. Puppet’s answer to this is environments. The documentation says that you can have arbitrary environments and redefine your configuration parameters in puppet.conf based on which environment you wish your clients to use. The general idea is to have several environments like “Production,” “Development,” and “Testing.”

Now, for me this falls down when I want to break away from more standard development cycles that no longer fit in the dev->test->prod workflow. Or if I have groups of developers working on disjointed projects but don’t want to support completely separate puppetmasters with their own clients. Or when I want to follow git’s mentality of “branching is cheap; branch often.”

I’d like to be able to say `git checkout -b newfeature`, add some resources and templates, `git push`, and instantly use it on my clients. No reconfiguration of the puppetmaster needed. When I finish, `git checkout production ; git merge newfeature ; git branch -d newfeature` will put all aright again.

In puppet.conf I can use $environment to reference the current environment for setting modulepath and manifest, but I don’t actually need the [newfeature] environment declaration section in the puppet.conf. This allows me to create a config thus:

  environment = production
  manifest    = $confdir/environments/$environment/manifests/site.pp
  modulepath  = $confdir/environments/$environment/modules

  environment = production

This says that the master will base the manifest and module path on the environment, which is passed by the agent to the master. If I changed the [agent] section on a puppet agent to have environment = newfeature instead, then the catalog compiled by the master would be from /etc/puppet/environments/newfeature. If an agent does not pass the environment variable then the default production will be used. (Big Note is that your files and templates really only work cross-environment if you’re using modules. You can either clone all of your modules per environment, or you can have some modules be per environment and some be global. Check out Volcane’s blogpost on using your modules in this manner.)

Now that I have puppet set up to take arbitrary environments, lets make this useful. To implement it so that git branches are recognized as separate environments, I have to keep your puppet manifests and modules in git. (You’re already doing that, right?) Starting without any environments, I’ll rearrage my puppet configs to look like this:

     | puppet.conf
     | fileserver.conf
     - environments/
       - production/
         + manifests/
         + modules/

In the production directory I `git init ; git add .` (then considering that I have a gitosis instance set up and an ssh key ready to be used by the puppet user,) `git remote add origin ; git push origin master`. Now for the git hook I go open puppet-environments.git/hooks/post-receive and put this bourne code in, configured with my git repo url and the key by which my puppet master can pull from gitosis:

read oldrev newrev refname

BRANCH=`echo $refname | sed -n 's/^refs\/heads\///p'`
SSH_ARGS="-i /var/lib/puppet/.ssh/id_rsa"

if [ "$newrev" -eq 0 ] 2> /dev/null ; then
  # branch is being deleted
  echo "Deleting remote branch $BRANCH_DIR/$BRANCH"
  ssh $SSH_ARGS $SSH_DEST /bin/sh <<-EOF
    cd $BRANCH_DIR && rm -rf $BRANCH
  # branch is being updated
  echo "Updating remote branch $BRANCH_DIR/$BRANCH"
  ssh  $SSH_ARGS $SSH_DEST /bin/sh <<-EOF
    { cd $BRANCH_DIR/$BRANCH && git pull origin $BRANCH ; } \
    || { mkdir -p $BRANCH_DIR && cd $BRANCH_DIR \
         && git clone $REPO $BRANCH && cd $BRANCH \
         && git checkout -b $BRANCH origin/$BRANCH ; }

Now after I’ve cloned puppet-environment.git to my laptop for hacking, I can `git checkout -b newfeature` and end up with an exact representation of my production code, but free to be hacked on until it’s ready to be pushed and tested. Pushing will instantiate it in a new environment. After I’ve pushed, I can run `puppet agent --test --environment newfeature` on a puppet client and get a one-time run inside your newfeature environment, and it will revert back to production after that run.

Finally, what if I want my hosts to remember which --environment I last ran on it? Or how about being able to configure the nodes’ environment right from puppet? For that I can make a small module with a parameterised class called “environment.” Here’s my init.pp:

class environment($env = $environment) {
  file { '/etc/puppet/puppet.conf':
    owner   => 'puppet',
    group   => 'puppet',
    mode    => '644',
    content => template("environment/puppet.conf.erb"),

As the final step, I copy my clients’ puppet.conf to modules/environment/files/puppet.conf.erb and replace the environment = production section in [agent] with environment = <%= env %>.

Now I can add include environment in my base node or any node that you want to “remember” it’s environment given via --environment. If I’d like to configure a node to always use a specific environment then I can instead use class { environment: env => "production" } and it will always revert to the production environment.

Thanks to Marut and the guys at PSU for the inception!