One of the features I’m proud of in Shotwell 0.4 is our undo/redo system. (Kudos to Rob Powell for turning me on to the Command pattern.) Thanks to abstractions in our primary data structures, it was easy to build a set of base Command classes that deal with these generic objects in generic ways. That’s why our undoable crop command is only 13 lines of Vala code — and that includes the class boilerplate.
When Adam first spec’d Shotwell (wa-aaa-y back in February/March of last year), he generated a slew of tickets for features he knew we wanted eventually, but in no particular order of priority. We knew we wanted undo but didn’t know when we’d add it (or even what would be undoable).
When I first attacked the problem in November, I pointed out that coding undo does not give you redo for free. So, Adam created a separate redo ticket in case it had to go in later.
As it turned out, I implemented Redo alongside Undo. I was elbow-deep in the code and I could see how to get redo implemented on all the various commands, and sometimes in generic ways. (This is why crop’s so small.)
That was pretty satisfying, closing ticket #65 and #1001 in the same commit. Now, some of those tickets in between aren’t for Shotwell, but certainly a lot of them are. It felt like nailing the 7-10 split in bowling. I’m a horrible bowler, and I only remember making that shot once. Closing two tickets separated by 936 others is likewise satisfying.