From a96ea8d35d6a50e025ec00630afdb7031aeaa2e1 Mon Sep 17 00:00:00 2001 From: Denis Zhdanov Date: Wed, 6 Oct 2010 17:45:50 +0400 Subject: [PATCH] IDEA-59220 IAE at com.intellij.openapi.editor.impl.DocumentImpl.a Corrected caret positioning during auto-hard wrap --- .../editorActions/AutoHardWrapHandler.java | 13 +++++++------ .../intellij/openapi/editor/impl/DocumentImpl.java | 6 +++++- 2 files changed, 12 insertions(+), 7 deletions(-) diff --git a/platform/lang-impl/src/com/intellij/codeInsight/editorActions/AutoHardWrapHandler.java b/platform/lang-impl/src/com/intellij/codeInsight/editorActions/AutoHardWrapHandler.java index b23803abd1dd..c3b37c768c4d 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/editorActions/AutoHardWrapHandler.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/editorActions/AutoHardWrapHandler.java @@ -158,9 +158,15 @@ public class AutoHardWrapHandler { } final int[] wrapIntroducedSymbolsNumber = new int[1]; + final int[] caretOffsetDiff = new int[1]; + final int baseCaretOffset = caretModel.getOffset(); DocumentListener listener = new DocumentListener() { @Override public void beforeDocumentChange(DocumentEvent event) { + if (event.getOffset() <= baseCaretOffset) { + caretOffsetDiff[0] += event.getNewLength() - event.getOldLength(); + } + if (event.getNewLength() <= 0) { // There is a possible case that document fragment is removed because of auto-formatting. We don't want to process such events. return; @@ -188,12 +194,7 @@ public class AutoHardWrapHandler { change.change.setStart(wrapOffset); change.change.setEnd(wrapOffset + wrapIntroducedSymbolsNumber[0]); - int newCaretOffset = caretOffset; - if (wrapOffset <= caretOffset && newCaretOffset + wrapIntroducedSymbolsNumber[0] < document.getTextLength()) { - newCaretOffset += wrapIntroducedSymbolsNumber[0]; - } - newCaretOffset = Math.min(document.getLineEndOffset(line + 1), newCaretOffset); - caretModel.moveToOffset(newCaretOffset); + caretModel.moveToOffset(baseCaretOffset + caretOffsetDiff[0]); } private static class AutoWrapChange { diff --git a/platform/platform-impl/src/com/intellij/openapi/editor/impl/DocumentImpl.java b/platform/platform-impl/src/com/intellij/openapi/editor/impl/DocumentImpl.java index 336c1a561a1d..9011bd00647b 100644 --- a/platform/platform-impl/src/com/intellij/openapi/editor/impl/DocumentImpl.java +++ b/platform/platform-impl/src/com/intellij/openapi/editor/impl/DocumentImpl.java @@ -468,7 +468,9 @@ public class DocumentImpl extends UserDataHolderBase implements DocumentEx { return null; // suppress events in shutdown hook } DocumentEvent event = new DocumentEventImpl(this, offset, oldString, newString, myModificationStamp, wholeTextReplaced); - + //System.out.printf("%nbefore change: offset=%d, old text='%s', new text='%s', document modification stamp=%d%nDocument:'%s'%n", + // event.getOffset(), event.getOldFragment(), event.getNewFragment(), event.getDocument().getModificationStamp(), + event.getDocument().getText()); for (int i = myDocumentListeners.size() - 1; i >= 0; i--) { try { myDocumentListeners.get(i).beforeDocumentChange(event); @@ -484,6 +486,8 @@ public class DocumentImpl extends UserDataHolderBase implements DocumentEx { @SuppressWarnings({"ForLoopReplaceableByForEach"}) private void changedUpdate(DocumentEvent event, long newModificationStamp) { + //System.out.printf("after change: new modification stamp=%d%ndocument='%s'%n", event.getDocument().getModificationStamp(), + // event.getDocument().getText()); if (ShutDownTracker.isShutdownHookRunning()) { return; // suppress events in shutdown hook }