Skip to content

Commit c5a7d66

Browse files
authored
Fix post undo/redo caret position (#915)
1 parent af4c7c5 commit c5a7d66

File tree

2 files changed

+50
-12
lines changed

2 files changed

+50
-12
lines changed

richtextfx/src/integrationTest/java/org/fxmisc/richtext/api/UndoManagerTests.java

Lines changed: 29 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -44,19 +44,38 @@ public void incoming_change_is_not_merged_after_period_of_user_inactivity() {
4444
}
4545

4646
@Test // After undo, text insertion point jumps to the start of the text area #780
47+
// After undo, text insertion point jumps to the end of the text area #912
4748
public void undo_leaves_correct_insertion_point() {
48-
long periodOfUserInactivity = UndoUtils.DEFAULT_PREVENT_MERGE_DELAY.toMillis() + 300L;
49-
50-
write("abc def ");
51-
sleep(periodOfUserInactivity);
52-
53-
write("xyz");
54-
interact(area::undo);
5549

56-
write('g');
50+
write("abc mno");
51+
interact(() -> {
52+
area.insertText(3," def");
53+
area.appendText(" xyz");
54+
});
5755

58-
sleep(periodOfUserInactivity);
59-
assertTrue(area.getText().endsWith("g"));
56+
assertEquals("abc def mno xyz",area.getText());
57+
58+
interact(area::undo); // removes " xyz"
59+
assertEquals("abc def mno",area.getText());
60+
// ^
61+
assertEquals( area.getCaretPosition(), area.getSelection().getStart() );
62+
assertEquals( 11, area.getSelection().getStart() );
63+
64+
interact(area::undo); // removes " def"
65+
assertEquals("abc mno",area.getText());
66+
// ^
67+
assertEquals( area.getCaretPosition(), area.getSelection().getStart() );
68+
assertEquals( 3, area.getSelection().getStart() );
69+
70+
interact(area::redo); // restore " def"
71+
assertEquals("abc def mno",area.getText());
72+
// ^
73+
assertEquals( area.getCaretPosition(), area.getSelection().getStart() );
74+
assertEquals( 7, area.getSelection().getStart() );
75+
76+
interact(area::undo); // removes " def"
77+
interact(() -> area.insertText(area.getCaretPosition()," ?"));
78+
assertEquals("abc ? mno",area.getText());
6079
}
6180

6281
@Test

richtextfx/src/main/java/org/fxmisc/richtext/util/UndoUtils.java

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -214,7 +214,10 @@ public static <PS, SEG, S> UndoManager<List<PlainTextChange>> plainTextUndoManag
214214
* by {@code area.replaceText(change.getPosition(), change.getRemovalEnd(), change.getInserted()}.
215215
*/
216216
public static <PS, SEG, S> Consumer<PlainTextChange> applyPlainTextChange(GenericStyledArea<PS, SEG, S> area) {
217-
return change -> area.replaceText(change.getPosition(), change.getRemovalEnd(), change.getInserted());
217+
return change -> {
218+
area.replaceText(change.getPosition(), change.getRemovalEnd(), change.getInserted());
219+
moveToChange( area, change );
220+
};
218221
}
219222

220223
/**
@@ -223,7 +226,10 @@ public static <PS, SEG, S> Consumer<PlainTextChange> applyPlainTextChange(Generi
223226
*/
224227
public static <PS, SEG, S> Consumer<RichTextChange<PS, SEG, S>> applyRichTextChange(
225228
GenericStyledArea<PS, SEG, S> area) {
226-
return change -> area.replace(change.getPosition(), change.getRemovalEnd(), change.getInserted());
229+
return change -> {
230+
area.replace(change.getPosition(), change.getRemovalEnd(), change.getInserted());
231+
moveToChange( area, change );
232+
};
227233
}
228234

229235
/**
@@ -238,6 +244,7 @@ public static <PS, SEG, S> Consumer<List<PlainTextChange>> applyMultiPlainTextCh
238244
builder.replaceTextAbsolutely(c.getPosition(), c.getRemovalEnd(), c.getInserted());
239245
}
240246
builder.commit();
247+
moveToChange( area, changeList.get( changeList.size()-1 ) );
241248
};
242249
}
243250

@@ -253,7 +260,19 @@ public static <PS, SEG, S> Consumer<List<RichTextChange<PS, SEG, S>>> applyMulti
253260
builder.replaceAbsolutely(c.getPosition(), c.getRemovalEnd(), c.getInserted());
254261
}
255262
builder.commit();
263+
moveToChange( area, changeList.get( changeList.size()-1 ) );
256264
};
257265
}
258266

267+
/*
268+
* Address #912 "After undo/redo, new text is inserted at the end".
269+
* Without breaking PositionTests. (org.fxmisc.richtext.api.caret)
270+
*/
271+
private static void moveToChange( GenericStyledArea area, TextChange chg ) {
272+
int pos = chg.getPosition(), len = chg.getNetLength();
273+
if ( len > 0 ) {
274+
pos = Math.min( pos + Math.abs(len), area.getLength() );
275+
}
276+
area.moveTo( pos );
277+
}
259278
}

0 commit comments

Comments
 (0)