Archive for February 23rd, 2014

I liked the way Dabblet does autoindenting (entering a new line copies the whitespace from the beginning of the current line, so you keep the same level of indentation). So I added an option to bililiteRange(element).text() to do that. Now bililiteRange(element).text('text to insert', select, true) with true passed as the last option will autoindent. My Prism editor now has a check box to implement that.

The code to do this is in the bililiteRange utilities, not the original code.

I also added two more bililiteRange plugins:

bililiteRange(element).indent(tabs)
Prepends the string tabs to each line that contains part of the range. Thus bililiteRange(element).bounds('selection').indent('\t') to indent by one tab (and if you want spaces, use those instead; I won't get into Holy Wars).
bililiteRange(element).unindent(n, tabSize)
Removes n tab characters or sequences of tabSize spaces from the start of each line.

And, inspired by jQuery data, added a bililiteRange(element).data() that returns an object tied to element that can be used to store any data on that element (not the bililiteRange) without memory leaks. Thus bililiteRange(element).data().tabSize = 4 can be used in future calls: assert(bililiteRange(element).data().tabSize == 4). In fact, unindent above does exactly that if tabSize is not passed in.

I was just working on adding autoindenting to bililiteRange, and actually took advantage of the fact that I had an automated test harness in place for that library. So I actually used test-driven development: write the tests for the code that doesn't exist yet, then write code until they pass. It's an odd way of thinking, but I realized that it was more fun than my usual development cycle (remember, I'm a hobbyist, so if it ain't fun, I don't have to do it):

  • Think of problem that needs solving (interesting)
  • Write code to solve problem (interesting)
  • Write demo/test code (sort of interesting)
  • Run test-fail test-mutter at code-recode debugging cycle (frustrating)

With TDD, it's more like:

  • Think of problem that needs solving (interesting)
  • Write demo/test code (sort of interesting)
  • Run test-fail test-Write code to solve problem cycle (interesting)

The tedious "debugging" phase is swallowed up in the interesting "write code to solve problem" phase and I enjoy it a lot more. There's still some tedious debugging if the test doesn't work, but the test code is simpler than the "production" code and generally easier to debug. I have had some problems getting my head around testing asynchronous code, but that probably means I need to simplify the whole system.

Now I need to learn the discipline to keep to this style of development and I'll be a happier hacker.