I’ve been writing code for a command-line input buffer.
Seems a bit odd in this day and age, eh? OS X already has a command line implementation – several, in fact.
But this one’s for my home project, which is a curious combination of Web browser and command line tool.
Per the Windows port, this command line acts a little odd. You can move up and move down in the command history using the up and down arrow keys, but if you modify any of the previous commands, those changes don’t “take”. Only changes to the last command are remembered if you move up and down the history.
Oh, and the current command – the one you’re looking at on the screen at any particular moment – needs to be held in an external buffer controlled by the cross-platform engine.
I have an NSArray of all the previous commands, and logic to copy the proper entry in that array to the buffer if the user moves up and down through the command history, but that last command line makes things a bit more fiddly. If you move up, I have to remember the contents of it, even though I have to fill the external buffer with new contents. But I don’t want to add it to the history, because you haven’t pressed return yet.
I said “fiddly,” not hard. My particular solution was to add it to the history array anyway, for the benefits I get from reusing the code that copies from the array to the buffer. As soon as you move up, we enter this special “extra entry added” mode, which we leave again if you move all the way back down again, or hit return.
So I knew that whenever the current command index didn’t point to the very end, I was in my mode, but I found myself getting a little confused, not able to nail everything down, even though the code itself wasn’t very complex. I knew what I wanted, but the code didn’t look like what I wanted.
The solution (and the point of this long-winded entry) was all about naming. Instead of the logic looking like this:
if(mCurrentCommandIndex < [mCommands count])
I made it look like this:
if([self bufferTemporarilyAddedToCommands])
and exiting the mode, instead of looking like this:
[mCommands removeLastObject]
I changed to look like this:
[self removeBufferTemporarilyAddedToCommands]
Not rocket science, but it allowed me to see where the code was doing its job, and where it wasn’t, and make the appropriate corrections.
Oh, that, and unit tests.
P.S. Yes, I use PowerPlant-style variable prefixes in my Cocoa code. So sue me.