I haven't used many professional word-processing programs, I've only used Microsoft
Word. (Insert Microsoft joke here if you like.) And it doesn't use word-based undo and redo, it gathers up continuous sets of added or deleted text and undoes and redoes those sets. So if you type "Hello Word" and then backspace and type an "l" before the "d", you have two units that can be undone. Clicking Ctrl-Z changes "Hello World" to "Hello Word" and clicking it again makes the whole thing disappear.
Anyway I wrote a subclass of UndoManager that replicated that behaviour. Here's an excerpt from it:
And here's the (inner) ExpandableEdit class which it uses:
That's just a bleeding chunk of code, it won't compile as is. But it's the basic core of Word-emulating undo and redo.