3.2.13. Coming Around to Sublime Text

So, quite late to the party, I'm starting to come around to liking Sublime Text 2 after many months of using BBEdit 10 as my primary development editor. I still like BBEdit, but Sublime Text is starting to pull away.

Some of the things that I like about BBEdit is that it doesn't have this runaway set of extensions and packages. It just works pretty damn well out of the box. BBEdit also has a real manual. And a real preferences UI. BBEdit is fast, handles large files well, and is very Mac native.

I decided to take another look at Sublime Text recently. One reasons is that my previous script for integrating PyFlakes into BBEdit broke in BBEdit 10.5, and I was starting to lose time to little mistakes that PyFlakes can find before I restart a dev server. I had a "PyFlakes on Save" in TextMate that I was really starting to miss. I knew there was something similar for Sublime Text and wanted to check it out. Enter SublimeLinter.

I'm not a fan of keeping track of lots of custom little packages and learning them. I have important work to do, and one of the reasons I stayed away from Sublime Text was my worry that I would spend more time tinkering with it to make it useful than I would spend doing my work. However, on re-evaluating Sublime Text, the following built-in functionality is really killer and has caused me to seriously consider a full switch:

  • Knowledge of directories in 'quick open / open anything'. Neither TextMate nor BBEdit seemed to do this. I can have large Python customer or internal projects with many files named 'interfaces.py' or 'base.py' or 'configure.zcml'. Doing a quick open to get to one of those files in other editors hasn't worked out too well. In SublimeText, I can start typing the path and hit '/' to start matching against that subdirectory.
  • Open Anything rocks. Being able to not just jump to a particular file quickly, but to then navigate right into its classes/methods/etc, all from the keyboard, is again pretty damn amazing. And fast!
  • Multiple Selection. being able to quickly rename a variable or method and also change all of its other uses in one fell swoop is pretty neat. I've generally solved this with "use selection for find / use selection for replace" but Sublime Text's option seems even better.
  • Split Windows. TextMate 1 never offered this. BBEdit allowed splitting the same file, but I don't think it allowed splitting multiple files. In general, this problem is solved with multiple windows, but I've missed being able to split windows with different files like I could do so easily in Emacs and Vim. It's nice to have a fairly modern editor that is fairly native to OS X that does this. This is especially nice in the full screen and 'distraction free' modes that I like to hit from time to time.

Something that was bothering me back when I used TextMate, and Emacs (and sometimes Vim) before that, was how out of sync my home and work setups could get. I do very little coding at home any more, and any time I would open up my editor, all of the little settings and massages that I had set up at work wouldn't be there. BBEdit 10 solved this with some native support for storing preferences and snippets and scripts in DropBox. I found some tips and tricks for storing Packages and Settings for Sublime Text and they seem to work.

Labels: , ,

31.1.13. Refining my Work Contexts in OmniFocus

Contexts are a major component in the GTD system by David Allen, and thus figure prominently in OmniFocus. Understanding and working well within contexts is an ongoing process. Some are immediately understandable, such as "Grocery Store" or "Home". Some may be devices, such as "Phone". These are known physical limitations where an action can only be performed in that physical space or device.

My life doesn't involve a lot of physical contexts outside of errands (then grouped by a couple of common errand types, and then by store for anything really specific), home, and work. But 'Work' is where I do and use much of my planning. I found that just having that as a lone context didn't work for me. Years ago, I set up two sub-contexts, Coding and Office and that got me by for a while, with most work tasks being in Work : Coding. This is still the case today, but I've recently found that it's helped to create some additional contexts that revolve around tools and responsibilities.

My work sub-contexts:

  • Coding, wherein I do most of my work. This is the editor - terminal - browser cycle, usually. For the longest time, this context was synonymous with "@work", as it was, well, what I did.
  • Deployment, a newly created context. This also tends to involve the terminal, but doesn't really depend on the editor or other bits. It tends to mean kicking off some automated scripts and keeping an eye on them. I separated it out into its own context so that I could see these separately from all of the potential coding "next actions", as deployments may have a higher or different priority. For example, I can deploy while eating lunch at my desk, so I might let these pile up from various other projects.
  • Research. The actions in here vary, but being in this context often signifies needing to crawl through code, archives, or the internet to learn something new or be reminded of how something works.
  • Basecamp, for needing to interact with the Basecamp project management system. The actions for this could mean just marking a task assignment as complete, or it could mean needing to write a message or comment to communicate with the team. I found that these kinds of actions were starting to slip from my head.
  • Agenda for anything I need to bring up at a meeting.
  • Documentation for tasks needing a bit of extra focus for writing and publishing.
  • Office for anything generic that can only be done at the office. This might mean something that requires a printer (I have none at home), or it might mean something I need to pick up or drop off at the office.

The nice side of this is that I can just park OmniFocus on my iPad in the "Work" context and see the available actions in all of these sub-contexts. The context they're in might let me know the time or tools involved, and that can help me make decisions about what to do next when I have multiple things happening at or near the same time. For example, I met let a couple of deployment tasks queue up, or I can do a deployment task while working on another project's coding task, as deployment requires little physical or mental labor but may require a lot of watching and waiting for changes to roll out across our servers. My Basecamp tasks can queue up for the end of the day, and have been helpful in reminding me to update our central project system used for company communication.

There seem to be some people these days wanting "multiple context assignment" in OmniFocus. I do not. I'm happy with the hierarchical context system. When in work mode, I can choose the level at which I want to focus and tune other things out. OmniFocus's hierarchical contexts also make re-organization easy without losing assignment. If a certain hierarchy isn't working out, I can change it with some dragging and dropping. This has helped keep my system functioning for me as my needs and expectations have evolved over the years.

Labels: , , , ,

19.12.12. Restoring Lost OS X Notes Folders
So I'm a loose fan of OS X's Notes app. It's simple - no having to think of filenames or storage, simple folders if needed, and it syncs everywhere. No dealing with Markdown. It's pretty damn close to a piece of notepaper.


Unfortunately, it has some weaknesses. And the most unfortunate weakness is that its data can be a bit fragile. The data is stored in IMAP on your mail server, and to keep things simple, I just had two folders in my iCloud mail account. All was going OK. Until the app had a mini-freakout earlier (it wasn't showing a cursor in the note area). I quit and reopened the app, and I was faced with a collection of local folders as well as iCloud folders. The local folders had 'recovered data', but I only had one new note in there. So I tried to empty and delete the 'recovered data' local folder.

Instead, I ended up accidentally deleting my Work Folder, and the ten or so notes I had in there. There was a warning dialog that popped up, but I thought it was in reference to the local folder and clicked through it.

So the notes were gone. I had to try to find them, but they were gone. The computer I was on didn't have Time Machine, so I had to hope that there was something I could go back in time and find at home.

Here's the location - {Home}/Library/Mail/{iCloud folder}/. I hit the time machine button once I was in there and was able to go back to yesterday and found a Work.mbox. I restored this .mbox folder, but that alone didn't cause the notes to come back. There are a bunch of folders and subfolders until one comes to .emlx messages. The easiest way to list all of them is to search for .emlx files. They don't open in Notes.app but they will open in Mail.app, with all of their formatting preserved. I imagine if you could open them in OS X 10.7 Mail.app, which still had the integrated Notes folders, you could move the messages into a new subfolder. But on 10.8, I had to manually copy the message text into Notes. It was only about 10 notes, so it wasn't bad. It's better than losing some of this data.

This did lead me to start looking at other options to handle short term reference that was as simple and convenient as Notes, but maybe with an easier-to-restore backup option, but I haven't found it. I am evaluating Evernote, but it feels more complex than what I use Notes for.

For me, Notes.app is a good place for temporary reference or some other minor/personal notes and lists. It's not a permanent archive, but it's a good place to collect thoughts before going into meetings or to hold onto some reference material from emails. Again, I don't need to think of filenames or tags or Markdown or anything fancy with it. I just wish it behaved a little better on OS X. I wish it was an iCloud Documents app that hid the file management part completely, but could take advantage of OS X document management (versions, time machine, etc).

Evernote may solve my problem of where to put notes after they're no longer needed in Notes.app, but feels a bit heavy for the use case outlined above.

Hopefully this is the only time I run into this problem.

Labels: , ,

3.11.12. On iPad Sizes
With the launch of the iPad Mini, Apple's 7.9" iPad, there seems to be a lot of "this is the future of the iPad" or "this is the iPad we'll all use" comments in various reviews I've read. Without having used one, I'll say differently.

When the iPad was announced in January 2010, there seemed to be a lot of discussion about whether the iPad was a device for consumption or creation, and about whether it could be a suitable laptop replacement. Nearly 3 years into the iPad era, there seems to be a consensus that this device is suitable for creation and it can be a laptop replacement or alternative for many. It is also an absolutely terrific machine for consumption of both text and media, but I think that it's usefulness as a creativity machine has surprised many.

I believe this is strongest at the 10" side. I think that the iPad Mini will be a nice creative machine, but early reviews and indications seem to indicate that people are finding it most useful as a "pick up and read/search/view" machine. The Mini is something they can use while pacing around and talking on the phone. It's smaller and lighter, which some say "is exactly what we all want out of our devices" (while at the same time everyone is saying the iPhone remains too small and should be bigger, and the oddly sized Samsung Galaxy Note has a surprisingly good number of fans).

Personally, I want my iPhone to be the size that it is. It fits well in my pocket, where it spends a lot of its time. I can keep it in my pocket when laying on the couch or in bed for a mid afternoon weekend nap, and it does not bother me the way bulky old cell phones did in the past. But I fear that if it were any larger, it would feel uncomfortable like a Moleskine notebook. I think the iPhone is the perfect size.

Likewise, I think the iPad's full size is also perfect for me. Let me list the ways I use my iPad:

  • OmniFocus. As a developer, my work desktop has a lot of apps and windows open, and keeping on top of my best laid plans was mildly annoying until the iPad came along. I do my planning on the iMac, entering in things I need to do to get some piece of work done, and then use the iPad as a separate dedicated screen for keeping on top of that list and marking things off. For a while, I was actually using a laptop for this, as that separate, dedicated screen makes it easier to find and reference what needs to be done when there are so many noisy resources needing my attention on my main work machine.
  • Reading. I eat at my desk a lot, either with local take-out or sack lunches from home, and the iPad, mounted on my Compass iPad Stand, makes for terrific reading and is a good size for at-desk reading whether using Kindle, iBooks, InstaPaper, DC Comics, The Economist, or the web itself. I know the "mini" size is supposed to be better for reading, but the 10" iPad is great for its placement and distance on my desk at lunch time.
  • Twitter. A wonderful, horrible distraction that is just a couple of swipes away while I'm working.
  • Writing. I'm writing this on my iPad on a crowded but cozy CB2 metal desk in the kitchen area of my loft. The 10" size works great for writing with iA Writer, Blogsy, the built-in Notes app, etc. The not-much-smaller 7.9" is probably fine, but for me, I no longer need a MacBook Air now that I've finally added a selectively-used keyboard to my iPad. Laptop replacement? You bet. I'm not programming on it, but I know now that I could probably use this with apps like Diet Coda to get some work done from home needed, although I do have good full-computer fallbacks for that.
  • Music. There are some terrific music apps for the iPhone and iPad, and the good iPad ones are quite terrific. Again, I find the larger screen works well for those apps. Some apps like the Korg iElectribe come close to matching the physical size of the full Electribe machines. The iPad is not yet an indispensable piece of my music setup, but it's a fun and useful addition on occasion.
There is also a lot of heavy consumption use in the evening as an IMDB and Twitter lookup machine while watching movies or TV that could possibly be served just as well by the iPad Mini, but the occasional video consumption (Netflix, Hulu, iTunes movies, HBO Go) also seem like they're better suited to this larger screen.

So for me, this 10" iPad is just fine. All of this talk about how we'll all be using 7 to 8" tablets is like saying we'll all be using the 11" MacBook Air and no one will use the 13"; or that no one will use a 15" laptop when there is a 13" available; or that no one will use a 42" TV when there is a 32" available. It all depends on need, use, and budget. Or as Horace Dediu says, it depends on the job(s) for which you're hiring the device.

I have never seen so much pointless talk over a device taking on an additional size as with the launch of the iPad Mini. It's just another size. It's not the second coming of the iPad, nor is it the doom. In my mind, there's nothing that exciting about the iPad Mini at all. I'm not saying its a bad device, it's just what it is: a smaller iPad.

Wake me up when there's a 13" iPad and iOS finally grows support for intelligently dealing with different scales and dimensions.

 

Labels: , , , ,

29.11.10. Keeping History

Back in mid 2005 I worked on a project for customer wherein I was generating "Froogle Feed" data for the customer's e-commerce sites. For some reason, the project never went live. Suddenly, a request shows up from the customer mentioning "Froogle Project" and asking for a couple of features.

I have no memory of how I accomplished this project in the first place. I don't know if the customer does either. I just have a couple of features in an email project and zero context. Does the customer remember the experimental work we did a couple of years ago? Does he remember the UI?

The big problem is that aside from a couple of emails and basecamp messages, and a couple of generated 'feed' files, I have nothing for this project. Looking through source code history returns nothing. Looking through the current site (an old Zope 2 based site, built out of page templates, python scripts, and SQL Methods) yields nothing either. Unfortunately, there's not a lot of history in the site. And if the feature in question never went live, there's (of course) not going to be ANY history.

I dug through a big folder of printouts and such collected over the eight-plus years of history with this customer. Nothing.

I finally turned to notepads and notebooks, and did manage to find a couple of notes in a couple of different places. And digging through some basecamp messages yielded a mention of a 'froogle.py' file in a development instance that was not put into source control (CVS at the time). That development server was killed off long ago. It may have been hobbling around, but after moving offices twice in the last year or so, the number of internal servers is nearly zero. Long unused development servers tend not to get plugged back in.

Some lessons learned:

  1. Always put a date stamp on handwritten notes. This is now a habit for me, but it apparently wasn't a habit back in 2005. I did find some dates on some pages and used that to backtrack to when this work was initially done (using date stamps on Basecamp and email messages). A side lesson to this is to always include the year when date stamping.
  2. Always use source control, even for unfinished projects. If this one file had been checked into CVS, I would be a bit less stressed right now. I'm far less familiar with this customer's site now than I was then and trying to remember how I built multiple Froogle files and put them into a Zip file would be great knowledge right now, even if the format has changed. Since moving to Git, it's easier to keep dead branches in the central repository. CVS made branching so painful that we never would start a 'froogle-feed' branch. Even if that branch never goes live, it's damn useful to have.
  3. Don't trust development servers. They may not be around forever, and odd little unfinished files or projects can get lost very easily over time. May not seem like a big deal, but sometimes these little projects come roaring back to life after five years. We now do most of our development on our desktop machines. When we get a new machine, all of our files roll over. Central servers work if it's a central common copy (like a master account server). I've found that development servers just lose luster over time, and tend to get very far behind in terms of hardware and core OS performance. Plus they tend not to have the kind of machine/account migration tools that desktop OS's like Mac OS X have.

 

Labels: ,

2.12.07. Distributed VCS's are the Great Enablers (or: don't fear the repo)

The more I play with the new breed of VCS tools, the more I appreciate them. The older generations (CVS, SVN) look increasingly archaic, supporting a computing and development model that seems unsustainable. Yet most of us lived with those tools, or something similar, for most of our development-focused lives.

When I speak of the new breed, the two standouts (to me) are Git and Mercurial. There are some other interesting ones, particularly Darcs, but Git and Mercurial seem to have the most steam and seem fairly grounded and stable. Between those two, I still find myself preferring Git. I’ve had some nasty webs to untangle and Git has provided me with the best resources to untangle them.

Those webs are actually all related to CVS and some messed up trunks and branches. Some of the code lives on in CVS, but thanks to Git, sorting out the mess and/or bringing in a huge amount of new work (done outside of version control because no one likes branching in CVS and is afraid of ‘breaking the build’) was far less traumatic than usual.

One of those messes could have been avoided had we been using Git as a company (which is planned). One of the great things these tools provide is the ability to easily do speculative development. Branching and merging is so easy. And most of those branches are private. One big problem we have with CVS is what to name a branch: how to make the name unique, informative, and communicative to others. And then we have to tag its beginnings, its breaking off points, its merge points, etc, just in case something goes wrong (or even right, in the case of multiple merges). All of those tags end up in the big cloud: long, stuffy, confusing names that outlive their usefulness. It’s one thing to deal with all of this for an important branch that everyone agrees is important. It’s another to go through all of this just for a couple of days or weeks of personal work. So no one does it. And big chunks of work are just done dangerously - nothing checked in for days at a time. And what if that big chunk of work turned out to be a failed experiment? Maybe there are a couple of good ideas in that work, and it might be worth referring to later, so maybe now one makes a branch and does a single gigantic check-in, just so that there’s a record somewhere. But now, one can’t easily untangle a couple of good ideas from the majority of failed-experiment code. “Oh!” they’ll say in the future, “I had that problem solved! It’s just all tangled up in the soft-link-experimental-branch in one big check in and I didn’t have the time to sort it out!”

I speak from personal experience on that last one. I’m still kicking myself over that scenario. The whole problem turned out to be bigger than expected, and now there’s just a big blob of crap, sitting in the CVS repository somewhere.

With a distributed VCS, I could have branched the moment that it looked like the problem was getting to be bigger than expected. Then I could keep committing in small chunks to my personal branch until I realized the experiment failed. With smaller check-ins, navigating the history to cherry-pick the couple of good usable ideas out would have been much easier, even if everything else was dicarded. I wouldn’t have to worry about ‘breaking the build’ or worry about a good name for my branch since everyone else would end up seeing it. I could manage it all myself.

This is the speculative development benefit that alone makes these tools great. It’s so easy to branch, MERGE, rebase, etc. And it can all be done without impacting anyone else.

One thing that I often hear when I start advocating distributed VCS’s is “well, I like having a central repository that I can always get to” or “is always backed up” or “is the known master copy.” There’s nothing inherant in distributed VCS’s that prevents you from having that. You can totally have a model similar to SVN/CVS in regards to a central repository with a mixture of read-only and read/write access. But unlike CVS (or SVN), what you publish out of that repository is basically the same thing that you have in a local clone. No repository is more special than any other, but that policy makes it so. You can say “all of our company’s main code is on server X under path /pub/scm/…”.

And unlike CVS (or SVN), really wild development can be done totally away from that central collection. A small team can share repositories amongst themselves, and then one person can push the changes in to the central place. Or the team may publish their repository at a new location for someone else to review and integrate. Since they all stem from the same source, comparisons and merges should all still work, even though the repositories are separate.

Imagine this in a company that has hired a new developer. Perhaps during their first three months (a typical probationary period), they do not get write access to the core repositories. With a distributed VCS, they can clone the project(s) on which they’re assigned, do their work, and then publish their results by telling their supervisor “hey, look at my changes, you can read them here …” where here may be an HTTP or just a file system path. Their supervisor can then conduct code reviews on the new guys work and make suggestions or push in changes of his own. When the new developers code is approved, the supervisor or some other higher developer is repsonsible for doing the merge. It’s all still tracked, all under version control, but the source is protected from any new-guy mistakes, and the new-guy doesn’t have to feel pressure about committing changes to a large code-base which he doesn’t yet fully grasp.

But perhaps the most killer feature of these tools is how easy it is to put anything under revision management. I sometimes have scripts that I start writing to do a small job, typically some kind of data transformation. Sometimes those scripts get changed a lot over the course of some small project, which is typically OK: they’re only going to be used once, right?

This past week, I found myself having to track down one such set of scripts again because some files had gotten overridden with new files based on WAY old formats of the data. Basically I needed to find my old transformations and run them again. Fortunately, I still had the scripts. But they didn’t work 100%, and as I looked at the code I remembered one small difference that 5% of the old old files had. Well, I didn’t remember the difference, I just remembered that they had a minor difference and I had adjusted the script appropriately to finish up that final small set of files. But now, I didn’t have the script that worked against the other 95%. When I did the work initially, it was done in such a time that I was probably using my editors UNDO/REDO buffer to move between differences if needed.

Now if I had just gone in to the directory with the scripts and done a git init; git add .; git commit sequence, I would probably have the minor differences right there. But I didn’t know such tools were available at the time. So now I had to rewrite things. This time, I put the scripts and data files under git’s control so that I had easy reference to the before and after stages of the data files, just in case this scenario ever happened again.

I didn’t have to think of a good place to put these things in our CVS repo. I just made the repository for myself and worried about where to put it for future access later. With CVS/SVN, you have to think about this up front. And when it’s just a personal little project or a personal couple of scripts, it hardly seems worth it, even if you may want some kind of history.

Actually, that is the killer feature! By making everything local, you can just do it: make a repository, make a branch, make a radical change, take a chance! If it’s worth sharing, you can think about how to do that when the time is right. With the forced-central/always-on repository structure of CVS and SVN, you have to think about those things ahead of time: where to import this code, what should I name this branch so it doesn’t interfere with others, how can I save this very experimental work safely so I can come back to it later without impacting others, is this work big enough to merit the headaches of maintaining a branch, can I commit this change and not break the build….?

As such, those systems punish speculation. I notice this behavior in myself and in my colleages: it’s preferred to just work for two weeks on something critical with no backup solution, no ability to share, no ability to backtrack, etc, than it is do deal with CVS. I once lost three days worth of work due to working like this - and it was on a project that no one else was working on or depending on! I was just doing a lot of work simultaneously and never felt comfortable committing it to CVS. And then one day, I accidentally wiped out a parent directory and lost everything.

Now, in a distributed VCS, I could have been committing and committing and could have lost everything anyways since the local repository is contained there: but I could have made my own “central” repository on my development machine or on the network to which I could push from time to time. I would have lost a lot less.

There are so many good reasons to try one of these new tools out. But I think the most important one comes down to this: just get it out of your head. Just commit the changes. Just start a local repository. Don’t create undue stress and open loops in your head about what, where, or when to import or commit something. Don’t start making copies of ‘index.html’ as ‘index1.html’, ‘index2.html’, index1-older.html’ ‘old/index.html’, ‘older/index.html’ and hope that you’ll remember their relationships to each other in the future. Just do your work, commit the changes, get that stress out of your head. Share the changes when you’re ready.

It’s a much better way of working, even if it’s only for yourself.

Labels: , , , , , , , ,