@@ -390,11 +390,32 @@ public void setText(String what) {
390
390
// its absolute position (number of characters from the start), which isn't
391
391
// always perfect, but the best we can do without making a diff of the old
392
392
// and new text and some guesswork.
393
+ // Note that we cannot use textarea.setText() here, since that first removes
394
+ // text and then inserts the new text. Even with NEVER_UPDATE, the caret
395
+ // always makes sure to stay valid, so first removing all text makes it
396
+ // reset to 0. Also note that simply saving and restoring the caret position
397
+ // will work, but then the scroll position might change in response to the
398
+ // caret position.
393
399
DefaultCaret caret = (DefaultCaret ) textarea .getCaret ();
394
400
int policy = caret .getUpdatePolicy ();
395
401
caret .setUpdatePolicy (DefaultCaret .NEVER_UPDATE );
396
- textarea .setText (what );
397
- caret .setUpdatePolicy (policy );
402
+ try {
403
+ RSyntaxDocument doc = (RSyntaxDocument )textarea .getDocument ();
404
+ int oldLength = doc .getLength ();
405
+ // The undo manager already seems to group the insert and remove together
406
+ // automatically, but better be explicit about it.
407
+ textarea .getUndoManager ().beginInternalAtomicEdit ();
408
+ try {
409
+ doc .insertString (oldLength , what , null );
410
+ doc .remove (0 , oldLength );
411
+ } catch (BadLocationException e ) {
412
+ System .err .println ("Unexpected failure replacing text" );
413
+ } finally {
414
+ textarea .getUndoManager ().endInternalAtomicEdit ();
415
+ }
416
+ } finally {
417
+ caret .setUpdatePolicy (policy );
418
+ }
398
419
}
399
420
400
421
/**
0 commit comments