Getting Things Done in a Nutshell

This is my first non-technical post, more to the topic of productivity and organization. (thought it only fair to warn people up front). I was originally going to write a post about GTD Apps online and in Mac OS X, but figured I should first gloss over GTD in general before being able to discuss the strong points of the various applications in any depth.

I currently follow (to use the term loosely) a methodology along the lines of “Getting Things Done” known to practitioners as “GTD”. It is a system developed by David Allen, in his book “Getting Things Done”. I am not going to delve too deep into the actual system. Its very flexible, very tool agnostic, and it is a system that focuses on the day to day grind of actually doing your tasks (as the name implies). This is a big departure from other established productivity books that tend to focus on your values, roles, responsibilities, and then assume that the day to day will take care of itself if you base all your decisions on your value system. It is these two aspects of GTD that has made it very popular with the geek set (web workers, programmers, bloggers, etc.)

GTD boils down to a few core concepts:

  1. Write shit down. Seriously. Everything. Technically you need to “capture” things in whatever is comfortable for you. If you live in email, anything important email it to yourself. If you want you can send yourself voicemail, whatever works for you. For most people its a combination of email, electronic notes and real paper notes. But since you have to write down EVERYTHING, its important your system be able to handle if you suddenly think of something while having dinner in a restaurant for example. The term David Allen uses is “ubiquitous capture”.
  2. Everything goes to your inbox. Everything you write, or think, everything someone else sends you, it goes to your inbox(es). You will probably have several. Examples of your inboxes are: Physical inbox, email inbox, your notebook, voicemail, everything needs to go to your inboxes, and you need to know what those inboxes are. (I mean really know your inboxes, like you should have a written list of them, and everything that matters to you should collect in oone of these places)
  3. Process your inboxes everyday, until they are empty. Your inboxes ARE NOT your system. They are the way things get into your system. Your email inbox does not do double duty as a task list. You need to have a system separate from your inboxes to organize your tasks so you can organize and process only what is new and not focus on things you have already figured out. Everything you have in your inboxes will be one of the following (and your system needs a specific place for each one)
    • Trash (duh)
    • Reference Material (again, self explanatory)
    • Projects / Next Actions: Project / Actions you are working on NOW, Projects / Actions / Things to Buy / Business ideas or whatever that you would like to do someday but are not planning on dong this in the near future
    • Tickler File: Things you want to “sleep on” and decided what to do with later on.
    • Someday / Maybe LIst: Things you would like to do, as the name implies someday, or maybe. Things like Travel to japan, Learn to play guitar, buy sailboat, clean out attic. YOu think you might want to do these things at some indeterminate point in the future, but have not committed to them.
    • Calendar: Appointments and other truly date specific items (not the things you would like to have done by a certain time, but might push back or something, that belongs in the tickler)
  4. Make sure to separate your Projects from your Actions. Your actions should be atomic things, one simple task you can look at and do. Its easy to identify some projects, like “write drawing application” The rule is, whatever actions are on your to-do list should be only one step, broken down as small as possible. For example, you should not list “design database schema”as a task, because that has multiple steps. You might: list data that needs to be stored, list possible future storage needs of application, list database servers that are available options. research available database server options, create feature matrix for database servers, draw schema diagram, write SQL create statements based on diagram. Even seemingly simple tasks like “clean out garage” have many tasks involved that you should consider.
  5. If you have more than 25 “Next Actions” split them according to where you can do them, the lists should determine themselves organically, like a to-do list darwinism. If you make a lot of phone calls, you should have an at phone to-do list with calls you need to make, whether to clients or the cable company. If you have a lot of tasks that need you to be at your computer, that should be a list. Other examples are: Home, Work, Online, Email, Errands. This is the sort of thing that requires experimentation and observation. For example I frequently have a list of items to enter into quicken, so I like to list them together, that has worked well for me. I never really had a lot of phone calls to make, so the Phone list didn’t make sense for me (I tried It).
  6. Everyday, anything in your tickler file for today should go into your inbox.
  7. Review your system every week, check up on your projects, review your Someday Maybe list, and go over your notes and all that of the past week to see if there are any reference items, inbox items in your head that you did not put into your inboxes.

That is GTD in a nutshell. I definitely do not do it justice here, and if anyone reading it would like to know more about it, I seriously recommend reading the book, or at least listening to the Audiobook (thats what I did the first time through). There are really only 2 criticisms that I can level against the system, and they are really just things that need to supplement it, not things actually wrong with the system:

  1. There is no methodology for habits. For example “Go to the gym”, “meditate”, “Run 5 miles a day”. Habits are an important part of being organized and “having your act together” but are not part of the GTD system. The tough part is not once the habit is in place, it is when you are trying to form the habit. The first 30 days you are trying to go to the gym 5 days a week, thats when you need to be organized about your habit. After that, its just a habit. There are a few ideas and proposals from GTDers out there about how to form new habits.
  2. It does not cover the Higher level thinking at all. For example the values and responsibilities you have that help you chose what is going to be a next action, and what action you aren’t going to do. Along those lines, I think its important to perform the exercises in “The 7 Habits of Highly Effective People”. Having your values clear to you means that choosing your next actions, is easy because they are what helps you accomplish your long term goals and are in line with your values. If your Values / Goals should be in place before doing GTD to help you organize your Next Actions, or you should instead Organize your actions to have the time and freedom to determine your Values / Goals is like a chicken and egg argument within GTD. More accurately, its probably neither of the two and more of an iterative process. While GTD speaks of working at different Altitudes ( runway is just doing your tasks, Values at 50,000 feet, Life Goals at 40,000 5 year goals at 20,000 and so on ) there is very little discussion of the higher levels. The System is a System for 10,000 feet and runway.

I plan to explore some of these points in greater depth later on in my blog. I also plan to add feeds that will allow you to filter on topic, so if you just want programming tips, you don’t have to read about GTD, and on the flip side you want to read about Productivity and don’t care about programming, you can also read only the posts you care about (after all, part of GTD is simplifying, and eliminating inputs that don’t give you any value).

Tips for Following the CocoaCast with XCode 3

I imagine a lot of programmers out there have similar issues to mine. I meant to learn Cocoa a while back, as a programmer and Apple switcher. But I never got around to it. Fast forward to March 2008, I still haven’t started learning Cocoa, and now the iPhone SDK comes out! I guess its time to learn!
Of course, I first assumed I would just plow through it. I downloaded the first SDK the day it became available, ripped into the sample projects that were online and looked at the code, I honestly could not make heads or tails of a lot of it. I could figure out what code was building the interface elements, and I could see the dummy arrays that were feeding into it, and had a vague idea of most of the syntax (I had programmed in C and C++ but never in Objective-C). No, If I was going to program for the iPhone (and of course all sorts of crazy app ideas were racing through my mind), then I was going to have to properly learn how to program Cocoa and Objective-C.
After a bit of googling about, I found the perfect resource:
Cocoacast and it used as its Textbook: “Cocoa Programming for Mac OS X” by Aaron Hillegass
It is a very laid back video podcast where the podcaster instructs and screen-casts lessons based on those in the book. It is a very friendl and warm style, but at the same time structured (since it follows the book and has homework), so anyone that wants a college-type environment will find this particular format very enjoyable as well.
Of course, I was anxious to learn, so I started following the podcast without first purchasing the book, and noticed that some of the initial dialogs (creating projects and files, etc.) were a bit different, but I managed to follow along.
Then in the screencast, he began linking some objects to controls in the window and it was completely different, this was when I realized, that the book and the podcast were written for XCode 2 / 2.5, the latest version (the one that came with the iPhone SDK) was XCode 3! Luckily, Google has all of the answers, and this time, it pointed me to the publisher’s website.
I would like to state at this point that I DO plan to purchase the book. However, I am holding out for the version based on XCode 3 (the 3rd Edition), which should be published on May 26th according to Amazon.
I have had very little issue now until I began to follow the exercise regarding a Document-based application. When I created the project, I was greeted by XIB files instead of NIB files. I researched (googled) but no one else had written anything about this. I then decided to install XCode 2.5 on a second computer, and generate an empty document based cocoa application, zipped up my project, and used this as the basis of my exercise. (the RaiseMan exercise).
If I was doing something wrong (it IS odd that nothing turned up when I googled things like “xib vs nib raiseman”), perhaps selecting the wrong kind of cocoa document-based application project…please tell me so that I can post a correction to this post.
Until I stand corrected, I will assume that other people might run into the same problem. To remedy the situation and help other budding Cocoa Programmers out there, you can download an empty document-based XCode 2.5 Project.

Elements of Javascript Style

Javascript is a very forgiving language to program in. As such, everyone has their own way to program it.

My personal Javascript style is continuously evolving thanks to everything I learn from watching YUI’s Crockford videos.

At the moment, I try to approximate most of Yahoo!’s design choices when creating a custom library for a site.

I begin by creating a namespace I will use for all scripts within the site. for example, if it was a script for this site I might go with Ebetan (I am a lazy typist), for the Widget Company, I might go with Widget or Widgetco. the idea is to have a Unique name for a global (Singleton) javascript object where all the scripts and objects you create can reside to avoid any naming collisions with other libraries / scripts you might use (or hack together on the fly). Javascript operates in global scope by default, which can easily create problems for programmers that are new to the environment.

[code lang=”javascript”]
var Foo = {};
[/code]

right above that, I like to create a $ function that is simply a wrapper for YAHOO.util.Dom.get. This makes syntax much cleaner than the typical document.getElementById. Its a convention that I copied from ProtypeJS.

[code lang=”javascript”]
var $ = function( elementId ){
return YAHOO.util.Dom.get( elementId );
};
[/code]

just below the declaration of the base class, I like to have commented out prototype methods for built-in classes. It makes it very easy for add a prototype method to a class just by commenting out the required lines, but at the same time I don’t weigh my code down with a bunch of prototypes I’m not actually using, and since I usually minify my javascript before closing out a project, I don’t have to worry about slowing down the download of the files(comments will just get removed). Here are most of the prototypes that I use (for the sake of appearance, I removed all of the ones that were more than one line, and a few of the longer ones

[code lang=”javascript”]
// Array.prototype.forEach = function(f){var i=this.length,j,l=this.length;for(i=0;i<l;i++){if((j=this[i])){f(j);}}};
// Array.prototype.contains = function(element){for(var i=0;i<this.length;i++){if(this[i]==element){return true;}}return false;};
// Array.prototype.clear = function(){this.length=0;};
// Array.prototype.shift = function(){for(var i=1;i<this.length;i++){this[i-1]=this[i];}this.length=this.length-1;};
// Array.prototype.unshift = function(item){this[this.length]=null;for(var i=1;i<this.length;i++){this[i]=this[i-1];}this[0]=item;};
// Array.prototype.sort = function(){var tmp;for(var i=0;i<this.length;i++){for(var j=0;j<this.length;j++){if(this[i]<this[j]){tmp=this[i];this[i]=this[j];this[j]=tmp;}}}};
//
// String.prototype.scan = function(pattern,iterator){this.gsub(pattern, iterator);return this;};
// String.prototype.strip = function() {return this.replace(/^s+/, ”).replace(/s+$/, ”);};
// String.prototype.stripTags = function(){return this.replace(/]+>/gi, ”);};
// String.prototype.escapeHTML = function(){var div=document.createElement(‘div’);var text=document.createTextNode(this);div.appendChild(text);return div.innerHTML;};
// String.prototype.unescapeHTML = function(){var div=document.createElement(‘div’);div.innerHTML=this.stripTags();return div.childNodes[0] ? div.childNodes[0].nodeValue : ”;};
// String.prototype.toArray = function() {return this.split(”);};
// String.prototype.toDom = function(){var div=document.createElement(‘div’);div.innerHTML=this;return div.firstChild;};
// String.prototype.trim = function(){return this.replace(/^s+|s+$/g,”);};
// String.prototype.reverse = function(){return this.split(”).reverse().join(”);};
[/code]

at the bottom of the file, I like to cover myself for browsers that have not implemented console.log

[code lang=”javascript”]
try{console.log(”);}catch(e){var console={log:function(){}};}
[/code]

If my project will be using Ajax (most of them have at least a little) I like to occasionally use a modal loading window when something sensitive is changing on the screen. Luckily, YUI has some sample code on how to use their libraries for just this purpose, I of course integrate this code into my class.

[code lang=”javascript”]
loading_window:{},
loading:function(){
Foo.loading_window.show();
},
end_loading:function(){
Foo.loading_window.hide();
},
init:function(){
var modal = true;
Foo.loading_window = new YAHOO.widget.Panel(“wait”, {
width:”240px”,
fixedcenter:true,
close:false,
draggable:false,
zindex:50,
modal: modal,
visible:false,
shim:true
});
Foo.loading_window.setHeader(“Loading, please wait…”);
Foo.loading_window.setBody(‘<img src=”http://us.i1.yimg.com/us.yimg.com/i/us/per/gr/gp/rel_interstitial_loading.gif” />’);
Foo.loading_window.render(document.body);
},
[/code]

you should notice I have also created an “init” method, the idea behind this is to execute this method once the page is done loading (when the DOM becomes available). to do that I make this the last line of the javascript file

[code lang=”javascript”]
YAHOO.util.Event.onDOMReady( Foo.init, null, Foo );
[/code]

Now that I have this nifty little loader, I want to have an easy way to show it and hide it whenever i make an Ajax call. To do that, I have an minor abstraction of Yahoo!’s Ajax implementation. I add these two methods to my javascript file.

[code lang=”javascript”]
makeAjaxCall: function( url, params, parser, method, args ){
params = params || ”;
parser = parser || function(o){void(null);};
method = method || ‘GET’;
args = args || {};
args._ajax_call_url = url;
Foo.loading();
var callback =
{
success:function(o){
parser(o);
Foo.end_loading();
},
failure:function(o){
Foo.log(‘There was an Ajax Communication Error calling : ‘+o.argument._ajax_call_url);
Foo.log(‘The Status was: ‘+o.status+’ ‘+o.statusText);
Foo.end_loading();
},
argument:args
};
YAHOO.util.Connect.asyncRequest( method, url, callback, params );
},
sendFormByAjax: function( form_id, url, parser, method, args ){
parser = parser || function(o){void(null);};
method = method || ‘GET’;
args = args || {};
args._ajax_call_url = url;
Foo.loading();
var callback =
{
success:function(o){
parser(o);
Foo.end_loading();
},
failure:function(o){
Foo.log(‘There was an Ajax Communication Error calling : ‘+o.argument._ajax_call_url);
Foo.log(‘The Status was: ‘+o.status+’ ‘+o.statusText);
Foo.end_loading();
},
argument:args
};
YAHOO.util.Connect.setForm( form_id );
YAHOO.util.Connect.asyncRequest( method, url, callback );
}
[/code]

Now that we have this very useful base class, we want a way to easily hang second level classes from it (namely, now that I have Foo, I want to create Foo.Bar under it, and have methods like Foo.Bar.drink_beer(‘corona’). The ideal solution is to wrap up the logic for testing for existence of parent classes and creating the ones that don’t exist in a simple clean method. So we add a namespace method to Foo.

[code lang=”javascript”]
namespace: function() {
var a=arguments, o=null, i, j, d;
for (i=0; i<a .length; i=i+1) {
d=a[i].split(“.”);
o=window;
for (j=0; j<d.length; j=j+1) {
o[d[j]]=o[d[j]] || {};
o=o[d[j]];
}
}
return o;
}
[/code]

Now, even though I have made sure console.log is declared for browsers that don’t support it, sending code to production that uses console.log actively is not a good idea (certainly a better one that “alert();”, however. What I like to do is implement a log method, in this case Foo.log(), that simply wraps console.log. What the heck is the advantage of that? Simple, I also create a class property called “debug_on”. Foo.log will test if the value of Foo.debug_on is “truthy” if so, then log, if not do nothing. Now when I publish my code, I can just set debug_on to false. If I need to debug in production, a bookmarklet, firebug command, or greasemonkey script can override my personal client instance of the “debug_on” setting without disrupting the experience of other users. (I’ll show you how to do this in a later post).

[code lang=”javascript”]
debug_on:true,
log:function(msg){if(Foo.debug_on){console.log(msg);}}
[/code]

In the first level of the javascript class, I typically also have alot of convenience classes. For example, I have a standardized set of feedback divs and styles that I use, and I like to be able to easily use them from Javascript for Ajax and other interactions. I have a few class members for browser detection, and a few other utilities for form manipulation, dynamically determining the relative path of the script for other resources (css and images for example). Each of these items will also be covered in later posts

If you were playing along with the walkthrough, you probably pasted everything above in your text editor. If you are getting errors, check the commas between methods and properties, OR you could just download the sample file I created above from here. (see! laziness does pay off! At least once in a while!)

How I Use TextMate

All Programmers swear by their editor. Its like a religion. You only need to think about the ongoing joke of emacs vs vi in the Unix world to get a sense of the fact that its not something we take lightly.

One very popular choice of editor on Mac is Macromates’ TextMate. Just like the two iconic Unix editors, the power of TextMate lies not within the application itself, although, it IS an incredible application, it fits in just seemlessly with the rest of the User Experience in OS X, and it integrates pretty nicely with popular Mac FTP client Transmit . No, the REAL power of TextMate lies in its plugin architecture. These plugins are called “Bundles”. And TextMate comes with a million of these right out of the box. This leads to people having different methodologies for how they like to use TextMate.

My career is in Web Development, so that is going to be the workflow I describe here. I also plan to use TextMate more for Cocoa / Objective-C as I learn the language, but for now I code that mostly in XCode.

I typically program in a very web-centric list of languages: PHP, Javascript, HTML, CSS, XML, SQL. The syntax highlighting for all of these is very good, its even smart enough to notice if I have SQL being set into a PHP variable and highlight that string appropriately. For example:

Picture 6.png

I would like drop-down autocompletion like what you see in alot of bloated IDE’s, but really, I know all these languages so well, that would just be indulging a lazy typist. For Javascript, YUI is typically my framework of choice, I have installed a Bundle for it that offers parameter help, tons of macros / code snippets whatever you want to call them, and highlighting of built-in YUI classes / methods.

I almost always work in “project mode”, not sure if thats the real name, but its what I call it. Its what happens when you open a folder with TextMate, you can do this by dragging the folder to the icon, through the command line utility (mate foldername/ ) or through Quicksiver (my personal favorite)

Picture 11.png

this will give you the “Project Drawer” which is the file browser type thing you are used to seeing in a lot of desktop text editors / IDEs:

Picture 10.png

If its a folder you work with frequently, you can save this as a project through File > Save Project As… , and then just open that file whenever you want the same folders loaded in your project drawer. You can use this project trick to get all your Transmit (FTP client) files to open in TextMate with tabs (instead of each file in its own window.)

I like to use the TextMate TODO Bundle to track points in my code where I have something to do(as the name implies), I can also flag code to fix with “FIXME” and mark any of these items as done with the keyword “CHANGED” in my comments. (I actually modified the plugin to use the word DONE instead, but CHANGED is the default) . The bundle works by placing specially formatted comments like so (either manually or by triggering the code snippet by typing “todo” followed by a TAB):

Picture 1.png

also works in HTML:

Picture 2.png

the bundle is smart enough to know the appropriate kind of comments for the language you cursor is currently sitting in.

you can then get a list of all your outstanding action items (or “Next Actions” for you GTDers out there) with a simple CTRL+SHIFT+T:

Picture 3.png

This methodology allows me to track what I need to do WHERE I need to do it. And the filenames you see on the left with the line numbers next to them are links that will jump right to that line in the file, and put your cursor there. (for the image above, note that I added my own “DELETE” comment and renamed “CHANGED” to “DONE” as I mentioned above..its amazing how easy this is to do if you go to Bundles > TODO > Preferences )

Picture 12.png

The only down side to this integrated work environment is that I’m not the only one using it. This way of working is also quite popular at Yahoo! (and apparently so is TextMate). The guys working on Ruby on Rails are also fans of TextMate, and its TODO Bundle. Especially its creator David Heinemeier Hansson and his team at 37 signals, if you have ever seen any of their rails screen-casts, you will notice they are working in TextMate. Cool, its a popular way to work, what’s wrong with that? Well, whenever I work in a project where I use YUI or Rails, and hit CTRL+SHIFT+T I not only get MY to-dos I also get all of the to-dos from those projects! Luckily I found the solution in this blog post:

Ex dolo with intent: exdolo.com

if you’re too lazy to click through to the post:

Go to Preferences → Advanced → Folder References and change the Folder Pattern from:

!.*/(.[^/]*|CVS|_darcs|{arch}|blib|.*~.nib|.*.(framework|app|pbproj|pbxproj|xcode(proj)?|bundle))$

to:

!.*/(.[^/]*|rails|CVS|_darcs|{arch}|blib|.*~.nib|.*.(framework|app|pbproj|pbxproj|xcode(proj)?|bundle))$

the equivalent expression I use for YUI:

!.*/(.[^/]*|yui|CVS|_darcs|{arch}|blib|.*~.nib|.*.(framework|app|pbproj|pbxproj|xcode(proj)?|bundle))$

Your milage may vary, I put all the YUI modules in the /js/yui/… directory of my projects, so filtering for the yui folder works for me.

The final piece of the puzzle is, of course, source control. I have a Subversion repository hosted at DreamHost. I simply followed these instructions for setting up a subversion repository, and just for kicks set up a Trac server. I really recommend using the HowTo and script posted here.

I then import / checkout my subversion repository from the command-line. It is very important to do your first checkout with username and password. A lot of Mac GUI clients try to make life too easy for you, and they will use the authentication credentials used to create the repository. I then install the Subversion plugin for Finder, and use the Subversion Bundle for TextMate (you knew that was coming, didn’t you).

Also, the subversion plugin for finder adds a little badge overlay to the icons in finder. Which is nice, because that same badge shows up in your title area in TextMate. see the little green dot with a check mark in the lower left corner of the html icon that tells me this is the latest working version of the file, a red dot with an “X” means my file has been locally modified, Yellow dot with questionmark means it doesn’t exist in the repository (needs to be added), and so on.

Picture 8.png

The subversion TextMate bundle has alot of advantages. For instance, I tend to work in a lot of different files in just a couple of hours. MVC development and Ajax work quickly increase the number of files you are touching. One Ajax call can involve the HTML page its its made from, a separate Javascript file, the PHP page receiving your Ajax call, and the controller underlying that page (hopefully you don’t need to touch the model.) After 3 or 4 hours of this, I have probably modified at least 10 files. This is where TextMate and the Subversion bundle make my life very easy. I can get the subversion status, which tells me what is modified, what files are not in the repository ( have a ? ), are added to the repository, but not had their first commit, etc. I can pull this status at the root of my project. With the project drawer open select the top-level folder and hit CTRL+SHIFT+A to get a context-type menu:

Picture 7.png

from this hit “0”…thats a zero, not a letter “o”. TextMate will generate a nice little report like this for you. And as an added bonus, its a completely interactive HTML form, you can add, diff, revert your files directly from the report, and then hit the commit button to commit all your work to the Subversion server!

Picture 4.png

Working with TextMate is absolutely the best experience I have had with a text editor / IDE. And I have tried more than a few, was actually quite happy with Zend Studio, and use it for its debugging, remote debugging capability, but I look forward to the day I can do this from within TextMate as well! If you are trying out TextMate, I recommend taking a look at the bundle it includes for the language you typically work in, by going to Bundles in the Menu, there are all sorts of cool stuff, for instance, PHP can execute the files and show you the output, or verify the file for syntax errors. Every couple of months I try a new editor (Alot of Ajax IDEs are coming out now a days!) but always find myself coming back.

Love TextMate? Hate it? Think I’m an idiot and should use BBEdit instead? Tell me in the comments!