Skip to content

Commit

Permalink
Correct the default plainChanges implementation and explain the quirk…
Browse files Browse the repository at this point in the history
…y code.
  • Loading branch information
JordanMartinez committed Mar 31, 2016
1 parent 0fea082 commit 4e6ce6b
Showing 1 changed file with 32 additions and 3 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,39 @@ public interface EditableStyledDocument<PS, S> extends StyledDocument<PS, S> {
ReadOnlyStyledDocument<PS, S> snapshot();

default EventStream<PlainTextChange> plainChanges() {
/*
The following code might seem a bit strange, but here's why it's used:
If a rich change is emitted that only changes the style, then inserted and removed are equal.
So, we want to exclude those style changes and only include changes where the actual text was modified
(e.g. some text was inserted/removed)
If we use the following code, "getText() is repeated twice:
richChanges().filterMap(
// excludes style changes
c -> c.inserted.getText().equals(c.removed.getText()), // first time
c -> new PlainTextChange(c.position, c.removed.getText(), c.inserted.getText() // second time
)
To prevent code repetition, we could map the RichTextChange to a PlainTextChange and then filter out
the PlainTextChanges that don't actually change anything (the RichTextChange was merely a style change)
However, this produces unneeded PlainTextChange objects.
So, to reduce code repetition and use less memory, the following approach is used.
*/
return richChanges()
// only allow changes that added/removed text; exclude style changes
.filter(c -> c.insertedLength() != 0 || c.removedLength() != 0)
.map(c -> new PlainTextChange(c.position, c.removed.getText(), c.inserted.getText()));
.map(c -> {
String inserted = c.inserted.getText();
String removed = c.removed.getText();
if (!inserted.equals(removed)) {
// if reached, the rich change was an actual text change, not a style change...
return new PlainTextChange(c.position, removed, inserted);
} else {
// if reached, the rich change was a style change; text wasn't modified
return null;
}
})
// now filter out the null values (the style changes) to insure no null events are emitted
.filter(c -> c != null);
}

EventStream<RichTextChange<PS, S>> richChanges();
Expand Down

0 comments on commit 4e6ce6b

Please sign in to comment.