- Project: Syntax Highlighting
- The API
- "Listening" for the Caret
- Doing the Highlights
- Running It
- Debugging: Indentation
- Conclusion
Debugging: Indentation
Any idea what's wrong with the following code?
if((c2 == '(' && c == ')') || (c2 == '{' && c == '}') || (c2 == '[' && c == ']')) { start = highlighter.addHighlight(openParen, openParen+1, goodPainter); end = highlighter.addHighlight(closeParen, closeParen+1, goodPainter); } else start = highlighter.addHighlight(openParen, openParen+1, badPainter); end = highlighter.addHighlight(closeParen, closeParen+1, badPainter);
It's from an early version of the highlighting software in the article. The symptoms that caused me to go out and debug were that the highlighting on the closing bracket was always turned on after the first one had been typed, as in Figure 5:
Figure 5 Why are the X's highlighted?
The trick, as the astute will already have noticed, is the lack of parentheses around the else clause. When the parentheses are matched (as they are in Figure 5), end was set twice: once for the good paint, and again for the one that should have been restricted to the bad paint.
The clear routine clears the current end highlight, but it can't do anything about the one that was lost when it was overwritten.
What can a programmer do to try to prevent errors like this? It helps to be tenacious about keeping your indentation current. Suppose the code had looked like this:
if((c2 == '(' && c == ')') || (c2 == '{' && c == '}') || (c2 == '[' && c == ']')) { start = highlighter.addHighlight(openParen, openParen+1, goodPainter); end = highlighter.addHighlight(closeParen, closeParen+1, goodPainter); } else start = highlighter.addHighlight(openParen, openParen+1, badPainter); end = highlighter.addHighlight(closeParen, closeParen+1, badPainter);
It would have been a lot clearer that something was wrong. To that end, I like to use an editor that will automatically maintain indentation for me: Emacs, in my case.
Some people like to solve the problem by using braces for every if. Then the same sort of syntax highlighter we were describing in this article would help. Personally, I think that uses up a bit too much valuable vertical space. A line with nothing but a brace on it uses up one of the sixty or so lines that I can fit on the screen at once, which limits the amount of code I can examine in a glance. Part of the reason this took me so long to find is that the code takes up 17 lines, because of its verbosity. I wanted to make really, really clear variable names, like highlighter, when hl might have done just as well, but for an article I wanted to be as clear as humanly possible. So each method call ends up taking three lines where it could have taken one.
It's all a matter of programming taste and tradeoffs. Whatever makes you most productive is best.