Zsh completion of arbitrary commands

I spent a good few hours over the weekend trying to figure out how do something with zsh completion that I figured would probably be quite simple but I just couldn’t find an example of anywhere.

I wanted to do tab completion based on the output of an arbitrary command.

This was so that I could make full use of AndyA‘s very useful directory shortcut pind script.

Essentially I was porting the _cdpin function from bash to zsh.


function _cdpin() {
local cur=${COMP_WORDS[COMP_CWORD]}
COMPREPLY=(
$( hasle ~/.pind -cx $cur )
)
}

complete -F _cdpin cdpin

It looked like it should be simple but after reading sections of the zsh manual, searching online, looking at the various completion scripts in my zsh installation and trawling Stack Overflow’s zsh content I couldn’t find a succinct example.

Eventually I found the answer in a book called From Bash to Z Shell which I was able to read on my Safari Books Online subscription.

The solution turned out to be ludicrously simple:


function _cdpin() {
compadd $(hasle ~/.pind -cx)
}

compdef _cdpin cdpin

I could make it even simpler if I stuck if in a file called _cdpin but I wanted to keep it in the same place as the functions.

Now when I type cdpin and hit tab I get a list of my existing entries and I can complete from there.

Annoying that something so simple was so hard to find so I’m posting it here in the hope it helps others.

And as AndyA was smart enough to share his scripts on github I’ve forked it and will add zsh support (via a conditional) and see if I can get him to pull in my changes (I’m sure he’ll do it if I buy him a beer).

As an aside, gotta say I’m loving github – I joined a few months back but have only just started uploading some code to it.

You can see my stuff at github.com/boncey.

Always be Debugging

Back when I was a Junior Programmer at my first programming gig I used to have conversations like this with my mentor.

Me: See, I enter the value here and then I get back the correct result. So, it works.

Mentor: Did you run it through in the debugger and see what the code was doing?

Me: I don’t need to, it works.

Mentor: It might be working just by luck, run it through and check.

I’d do as he said and run it through and around 50% of the time I’d spot something that could have gone wrong (we were writing C++, there was an awful lot that could go wrong).

So, gradually, I got into the habit of always stepping through any new code I had written in the debugger.

Now I’m more experienced I don’t do that so often (I tend not to make those silly mistakes so much – plus we have unit tests for picking up on said silly mistakes, oh yeah, and I no longer code in C++).

But one habit that has stayed with me is to always run my application in debug mode in Eclipse (I develop web apps in Java now).

That way if I do see something dodgy I can set a breakpoint, refresh the browser and immediately find out what’s going on.

The option to run my application in non-debug mode may as well not exist in Eclipse for me – I think I’ve only ever clicked that button by accident.

However, when I am asked by another team mate to help them out with a coding issue at some point we might have a conversation like this.

Me: Stick a breakpoint on that line there.

Team mate: I’m not running in debug mode, I’ll need to restart.

Me: Hmm, you should always run in debug mode, it’s great for things like this.

Team mate: Debug mode is slower.

Me: Restarting every time you have a problem isn’t exactly fast either.

I try not to go off on one at this point and lecture on the benefits of running in debug mode but I do think that stepping through code and seeing what’s going on can help can make people better programmers.

It’s not just the scenario described above.

If you’re running your application and see something not quite right it’s very easy to add a breakpoint and find out what’s going on.

If you’re not running in debug mode the temptation is to think “I’ll take a look at that later” and then forget all about it.

If you don’t already do this then you might want to try it for a week or two.

My betting is that you won’t switch back.

Automatically adding photos to Flickr photosets

I’m quite lazy when it comes to organising my photos into photosets on Flickr.

The whole process has always been a bit too manual for my liking.

It’s been on my todo list to find a way of automating it so this weekend I tried to do just that.

My thinking was to somehow link my photosets to the tags I already use for my photos. These are set when I upload from my photo database (photodb).

I know Flickr Set Manager already does this but I wanted something integrated into my photo database.

I’d already decided I didn’t want to store details of the photosets in my database as it would be a maintenance pain if I removed a set.

Plus I’d need to write some code and web pages for managing it all.

As I was pondering alternatives I had the idea to add some metadata to a photoset description on Flickr then parse and match on that in my app.

Cluttering up my set description with such metadata was a little messy but as you can’t add tags to sets it seemed the simplest way.

The basic plan then was to load all my photosets from Flickr when I chose to upload a photo.

Then parse the set descriptions for my metadata and match that against my photo’s tags.

This would then pre-select those sets in a multi-choice select box displayed on my upload page.

I could then de-select any incorrect choices and choose additional sets too.

Once I had knocked together a little prototype it occurred to me that as I store lots of other metadata about my photos I could automatically add to sets based on all sorts of criteria.

So I set about feeding location data, camera and film information into it too.

The really nice part about this solution is that if I want to create a new set based on a particular location or new camera I just need to add an entry into the set description and it all “just works”.

I mentioned above my plan to use a multiple choice select box – I forgot to mention how much I hate them though. Luckily for me I’m not the only one who hates them.

This article talks about various alternatives – the best one for me being the jquery-asmselect plugin which provides a clean and elegant solution to the problem.

Of course; all this only works for newly added photos. What about the 2000+ photos I already have on Flickr?

I need some sort of batch process to re-organise my existing photos.

Fortunately I’ve already written something similar for tagging photos which I can re-use.

Finally, here’s how it looks on screen.



If you click through to the photo on Flickr you’ll see notes I’ve added to explain things in more detail.

Dealing with the wardrobe from hell

I’ve been reading a lot about Minimalism lately.

It started when I heard about a site called Minimal Mac. That site led me to Zen Habits and then on to mnmlist and before you know it I’m reading a post about how to declutter a closet (or tidy a wardrobe as I call it).

Now I wasn’t really sure if I wanted to embrace the minimalist lifestyle or not but I did have a wardrobe that was in a right old state.

So posts like this tend to grab my attention.

I should stress – I don’t need to be told how to tidy my wardrobe, I just need to be told to clear out my damn wardrobe!

It’s a motivational thing.

And it seemed to do the trick as that following weekend I got started on the wardrobe from hell.

Getting started

There really was far too much stuff to tackle in one sitting.

So I logically divided it up into sections and did it over the course of several weekends.

I figured I’d lack motivation after a while and give up (this wasn’t the first time I’d tried to do this) but to my surprise the sense of accomplishment I got from clearing a section motivated me to do another section the following weekend.

The key thing was to make sure I had enough time to do a section completely so I could get that sense of accomplishment – the motivation killer is when you run out of time with the job half done.

Nobody wants to go back to a half-completed job.

Paper

I’m using the word “section” to mean any number of things.

Some “sections” were boxes of papers I’d been hanging on to for, um, several years.

Going through a box and deciding whether to shred, recycle or file away the papers inside was one of the tasks I dreaded.

There’s a reason there were papers inside going back years. I’d been putting off sorting through it for all that time.

Hmm, that was several dull afternoons of my life I’m never getting back.

No more random boxes

Other “sections” were boxes of stuff.

Generally speaking, I had two types of boxes; boxes of related things (like tools or camera gear) and boxes of random crap that didn’t seem to belong anywhere.

I wasn’t really concerned with the boxes of related things – I knew what was in them as I accessed them fairly regularly.

It was the random crap I had a problem with.

Boxes of random stuff are bad news.

As long as there is no rule about what does and doesn’t belong in them then effectively everything belongs in them.

And once you have a rule like that you’ll slowly but surely end up with a wardrobe that’s a big old tip again.

So, there will be no more random boxes.

If I really can’t figure out where something belongs then it’s quite likely I don’t even want it around.

I thought it would be quite hard to get rid of the stuff in the random boxes but it was fairly easy – most of it had been sat there untouched for years and really was junk.

Various bits already belonged somewhere else – camera bits or stuff for my bike etc.

The remainder ended up in the chuck pile.

Disposing of stuff

As for actually disposing of stuff.

Papers and bits of cardboard were all recycled (sensitive papers being shredded first of course).

Things like unwanted books, records and DVDs went to Oxfam (after being offered to friends – friends who clearly don’t share my tastes I might add!).

Unwanted electrical stuff went on either eBay or Freecycle.

Actually, hardly anything went on eBay – either everyone’s going minimalist or there’s a recession on as everyone was selling and nobody was buying.

Hmmm, I got rid of an all awful lot of stuff – I guess all that reading about minimalism has rubbed off on me after all.

Machine tags on Flickr

A friend recently alerted me to this post about machine tagging for film photos.

He suggested I might want to add similar tagging to FilmDev.

I did want to add machine tags to FilmDev (other than the obvious one it uses to link recipes to photos), but I was more interested in adding them to my own Flickr photos.

Because I always add my photos via the photo database webapp that I developed (photodb) it makes it fairly easy for me to add any style of machine tags I want to my photos.

Also, because I always store the Flickr photo id after uploading it makes it easy to re-tag all my existing Flickr photos too.

So I set about implementing it.

Using the really useful flickr machine tag browser (by Paul Mison) I was able to quickly determine the most sensible tags to add to my photos.

I have a mixture of film and digital photos on Flickr so had to come up with tags for both types of photos.

I ended up with this for digital photos:


camera:model=Canon EOS 20D
lens:make=Canon
lens:model=Canon17-85f/4.0-5.6
photodb:id=8429

I didn’t bother with tags for apertures and shutter speeds (even though I hold that information in photodb) as it seemed overkill for my uses.

I’ll come back to the photodb:id tag shortly.

For film photos I have something like:


camera:model=Olympus XA3
film:brand=Agfa
film:name=Agfa Vista 100
film:iso=100
film:format=35mm
photodb:id=15303

I don’t necessarily know what lens I used for a particular photo so I don’t record that and many of my film cameras don’t have interchangeable lenses anyway.

As I mentioned above I hold the Flickr photo id in photodb whenever I upload a photo so I am theoretically able to re-tag all my photos.

To do this I wrote the back-end code to set tags on a photo (photodb is written in Java) then hooked up an Ajax action to it.

I dug around for something I could use to show me the status of my re-tagging action (I had about 1700 photos to tag) and found JQuery PeriodicalUpdater so I wired that up to give me a countdown.

The last thing to mention is the photodb:id machine tag – predictably enough it refers to the id of the photo in photodb.

I hacked together a quick greasemonkey script to check for this tag and generate a link to that photo in photodb.

This makes it super-easy to link between the two websites (the ability to do that has been on my todo list for ages).

Oh yeah, as to the request to add them to FilmDev that prompted all this, I am still working on that (along with a bunch of other features).

Unlike photodb, real people use FilmDev so I can’t just hack together any old crap. 🙂

Wiphi update

I recently blogged about buying an Acer Aspire Revo to sit under my TV.

It arrived as planned and setting it up was fairly straightforward.

I’ve had it for about six weeks and I’m mighty pleased with it.

It’s small, quiet and looks pretty cool too.

I plumped for Boxee as an interface to my music and videos and although it crashes now and again I quite like it.

It crashes less now that I am using the standard Ubuntu nVidia drivers from apt (I previously downloaded the latest drivers from the nVidia site but half my videos wouldn’t even play).

It runs so quiet I have now set it up to run email, DNS and DHCP thereby enabling me to shut down the large (noisy) tower PC that was previously performing those tasks.

I reckon with the electricity I save it’ll have paid for itself in 2-3 years!

Boxee has really impressed me.

The ease with which I can play videos has got me ripping my existing DVDs so I can watch them through Boxee.

For me at least the age of disk-based media has passed – I can’t be doing with disks anymore.

Much as with my CDs once I rip them I put them in a box at the back of a cupboard and never refer to them again.

Wiphi Mark II

Almost five years ago I decided to build a “DIY streaming media thingy” to play music in the living room.

I went ahead and built it and very good it was too.

But it’s been getting a bit long in the tooth and it is a little too large for the TV stand so I have reluctantly decided to retire it.

The idea of doing without a PC in the living room lasted about two days before I was back on QuietPC planning Wiphi Mark II.

I had my eye on a case but after doing the maths I realised it was going to cost a fortune to build a new PC from scratch.

I was just about ready to abandon my plans when I caught sight of one of these on The Gadget Show.

I got even more excited when I found out there was a Linux version for £180 (annoyingly they were going for £150 a few months ago).

The Linux versions do seem to be rarer than hen’s teeth at the moment but I managed to track one down from eBuyer eventually.

Software wise I think I’m going to try out Boxee instead of my homebrew Wiphi code – I’m a little sad to give up on it but it’s quite clunky and basic compared to all the whizzy stuff you get with Boxee.

I’ve also found a useful guide to getting it all set up.

It arrives on Saturday.

That’s my weekend sorted then. 🙂

The development of FilmDev (part one)

So, a while back I blogged about wanting to learn a new programming language.

A mere year after that I actually started doing something about it and a full year on I have some real progress to report!

I’d decided to learn Ruby and as I’m a Web developer by trade I decided to take a look at Ruby on Rails.

My first project was a very basic “point rails script at database” application to track the stupid amounts of photographic film that I keep buying on eBay.

It was simple to set up but as it was little more than a glorified spreadsheet I didn’t feel I had learned a lot about Ruby and/or Rails (it really helped me get my film addiction under control though).

I needed a meatier project to get stuck into…



Architecture – boncey

About this time I’d started developing my own black and white film.

I’d been umming and ahhing over doing it for quite a while and after reading dozens of “It’s easy!” type posts on various film groups on Flickr curiosity overcame my inertia and I decided to take the plunge.

Turns out they were right; it was quite easy. Even the dreaded “getting the film onto the damn reel in pitch darkness” bit seemed to go well (a combination of luck and a brand new Paterson reel I suspect).

As I only had Ilford film I followed their instructions, using Ilford DD-X as my developer.

Of course, there’s no rule saying you have to match a particular film with a particular developer – part of the fun of home developing is experimenting with different combinations.

It was whilst ruminating over this that I was struck by the idea that it would be really useful if there was a Website that provided an easy way to compare the results of developing a particular film with a particular developer.

The basic principle would be to allow people to sign in and describe what method they used to develop a particular film – a film developing “recipe”.

These recipes could then be linked to photos on Flickr via a special tag.

Thanks to the Flick API this would all be fairly straightforward to put together.

This then would be my first proper Rails project.

I started the project around the beginning of March 2008 and announced it to the world about 5 weeks later.

The site can be seen at filmdev.org.

Although the initial version was basic, it fulfilled my brief, which was to learn some Ruby (and some Rails).

But at this point I still had a lot of gaps in my knowledge.

My hosting solution was a bit ropey – relying on Fast CGI (hey, it seemed like a good idea at the time!).

And such wonders as Capistrano were still a closed book to me.

I still had a lot to learn…

NVIDIA drivers in Ubuntu 8.10 (Intrepid Ibex)

I upgraded from Kubuntu 7.10 to Ubuntu 8.10 this morning.

This was via a fresh installation into a new partition.

Getting it running went fairly smoothly but trying to get the NVIDIA drivers working was a world of pain.

It seemed that no matter what I tried I always got the following error:

Failed to load the NVIDIA kernel module

Every tip and bit of advice I found online didn’t work.

It turns out that the linux kernel headers aren’t installed by default but are required by the nvidia drivers (I only wasted two hours finding this out!).

It’ll never work unless you install the linux headers first.

These commands fixed it for me (exact version numbers may vary according to current Linux kernel version and your particular video card).

apt-get install linux-headers-2.6.27-7-generic

apt-get install nvidia-glx-177

Hope this helps someone.

cdripper

As a follow-up to yesterday’s post on importing CDs I’ve decided to add my CD importing code to github.

It lives here.

I suspect it’s more useful as source code for people to look at than as a project for people to use.

It’s a little bit too much “MeWare” at the moment for it to be generally useful.

Of course, it would not be that much work to make it more generally useful:

  • Put all the paths to binaries in a config file (they’re currently hard-coded in the source).
  • Write some documentation (it has JavaDoc but that is all).
  • Make it a little more flexible (it makes some assumptions about output files with specific names and in specific formats).
  • It’s only ever been run on Linux (I’m not sure if all the binaries it requires exist on Windows)

Plus, there are a million and one programs out there to rip CDs (this is the bit where I’m supposed to justify writing yet another one…).

Anyway, the code is available to browse so feel free to “check it out”.