I'm a little drunk right now, so this may come out slightly garbled. I want
to talk a little bit about performing find/replace operations with styled text.
Historically, performing find/replace operations with styled text has always
caused problems. The issue is that the style-runs (either in "styl" resources
in Ye Olden Days, or probably in attributes dictionaries in NSAttributedStrings
nowadays), are <em>separate</em> from the text. Thus, with a naïve implementation,
you get a classic "bug": after a replace operation, either all text in the document
(for <em>very</em> naïve code), or all newly-inserted text, inherits the style
information of the first character of that section of text. This is the classic
styled-replace problem.
The question is, do we just accept this behaviour? After all, the user can't reasonably
expect much more, can they? Actually, they can and do expect more. Clearly, a more intelligent
implementation is required. There are essentially four scenarios to consider:
- The replacing text is the same length as that which it replaces.
- The replacing text is shorter.
- The replacing text is longer, but has a non-zero length.
- The replacing text has zero length.
Let's deal with the above scenarios one by one.
Scenario 1: Same length
This is easy; just maintain the style-runs character-by-character. For situations
where double-byte text is present, proceed on a "one <em>visual</em> character" basis.
Scenario 2: Replacing text shorter
In this case, proceed as with the "same length" situation, but truncate the style-runs
after the appropriate number of characters.
Scenario 3: Replacing text longer
This is the trickiest situation. It's probably most intuitive to again maintain the style-runs
character-by-character until you run out of style information, and then assign the style information
of the last (old) character to all successive characters in the new text. This makes sense to the user,
because when you continue typing at the end of some styled text, the new text invariably inherits the
styles of the previous character.
Scenario 4: Replacing text has zero length
This is obviously a deletion operation. Accordingly, it's important to make sure that the style-runs of
the deleted text are also removed; it's not acceptable to simply let the remaining text be "bumped along"
the underlying style-runs, and to simply chop off an appropriate quantity of style information from the
end. Usually this behaviour is taken care of automatically, but it's still worth mentioning.
So there you have it: sensible and reasonably intuitive styled-replace. Much more work for the developer,
but fewer bizarre bug-reports after release. Now I'm off to get another beer.