From dfdf234ea3fe23cc88a3313c6631541a8be52ec9 Mon Sep 17 00:00:00 2001 From: Dmitry Batrak Date: Fri, 25 Mar 2016 17:23:55 +0300 Subject: [PATCH] don't update selection on document changes in bulk mode (IDEA-153495) --- .../openapi/editor/impl/CaretImpl.java | 2 ++ .../editor/impl/SelectionModelImpl.java | 20 +++++------- .../openapi/editor/impl/EditorImplTest.java | 31 +++++++++++++++++++ 3 files changed, 41 insertions(+), 12 deletions(-) diff --git a/platform/platform-impl/src/com/intellij/openapi/editor/impl/CaretImpl.java b/platform/platform-impl/src/com/intellij/openapi/editor/impl/CaretImpl.java index 6ff0acc26ab3..f002d0d8bb6f 100644 --- a/platform/platform-impl/src/com/intellij/openapi/editor/impl/CaretImpl.java +++ b/platform/platform-impl/src/com/intellij/openapi/editor/impl/CaretImpl.java @@ -125,6 +125,7 @@ public class CaretImpl extends UserDataHolderBase implements Caret, Dumpable { Document doc = myEditor.getDocument(); if (myOffset > doc.getTextLength() || savedBeforeBulkCaretMarker != null) return; savedBeforeBulkCaretMarker = doc.createRangeMarker(myOffset, myOffset); + beforeDocumentChange(); } void onBulkDocumentUpdateFinished() { @@ -142,6 +143,7 @@ public class CaretImpl extends UserDataHolderBase implements Caret, Dumpable { } releaseBulkCaretMarker(); } + documentChanged(); } public void beforeDocumentChange() { diff --git a/platform/platform-impl/src/com/intellij/openapi/editor/impl/SelectionModelImpl.java b/platform/platform-impl/src/com/intellij/openapi/editor/impl/SelectionModelImpl.java index e1fd9955251c..01db347cb86b 100644 --- a/platform/platform-impl/src/com/intellij/openapi/editor/impl/SelectionModelImpl.java +++ b/platform/platform-impl/src/com/intellij/openapi/editor/impl/SelectionModelImpl.java @@ -53,15 +53,13 @@ public class SelectionModelImpl implements SelectionModel, PrioritizedDocumentLi private TextAttributes myTextAttributes; - private DocumentEvent myIsInUpdate; - public SelectionModelImpl(EditorImpl editor) { myEditor = editor; } @Override public void beforeDocumentChange(DocumentEvent event) { - myIsInUpdate = event; + if (myEditor.getDocument().isInBulkUpdate()) return; for (Caret caret : myEditor.getCaretModel().getAllCarets()) { ((CaretImpl)caret).beforeDocumentChange(); } @@ -69,16 +67,14 @@ public class SelectionModelImpl implements SelectionModel, PrioritizedDocumentLi @Override public void documentChanged(DocumentEvent event) { - if (myIsInUpdate == event) { - myIsInUpdate = null; - myEditor.getCaretModel().doWithCaretMerging(new Runnable() { - public void run() { - for (Caret caret : myEditor.getCaretModel().getAllCarets()) { - ((CaretImpl)caret).documentChanged(); - } + if (myEditor.getDocument().isInBulkUpdate()) return; + myEditor.getCaretModel().doWithCaretMerging(new Runnable() { + public void run() { + for (Caret caret : myEditor.getCaretModel().getAllCarets()) { + ((CaretImpl)caret).documentChanged(); } - }); - } + } + }); } @Override diff --git a/platform/platform-tests/testSrc/com/intellij/openapi/editor/impl/EditorImplTest.java b/platform/platform-tests/testSrc/com/intellij/openapi/editor/impl/EditorImplTest.java index 00c755610175..b816f326af19 100644 --- a/platform/platform-tests/testSrc/com/intellij/openapi/editor/impl/EditorImplTest.java +++ b/platform/platform-tests/testSrc/com/intellij/openapi/editor/impl/EditorImplTest.java @@ -22,6 +22,10 @@ import com.intellij.openapi.editor.Document; import com.intellij.openapi.editor.FoldRegion; import com.intellij.openapi.editor.LogicalPosition; import com.intellij.openapi.editor.VisualPosition; +import com.intellij.openapi.editor.event.CaretAdapter; +import com.intellij.openapi.editor.event.CaretEvent; +import com.intellij.openapi.editor.event.SelectionEvent; +import com.intellij.openapi.editor.event.SelectionListener; import com.intellij.openapi.editor.ex.DocumentEx; import com.intellij.openapi.editor.ex.EditorEx; import com.intellij.openapi.editor.ex.util.EditorUtil; @@ -329,4 +333,31 @@ public class EditorImplTest extends AbstractEditorTest { Rectangle visibleArea = myEditor.getScrollingModel().getVisibleArea(); assertTrue(visibleArea.contains(caretPoint)); } + + public void testCaretAndSelectionEventsInBulkMode() throws Exception { + initText("abcdef"); + StringBuilder output = new StringBuilder(); + CaretAdapter caretListener = new CaretAdapter() { + @Override + public void caretPositionChanged(CaretEvent e) { + output.append("caret:").append(e.getNewPosition()); + } + }; + SelectionListener selectionListener = new SelectionListener() { + @Override + public void selectionChanged(SelectionEvent e) { + output.append("selection:").append(e.getNewRange()); + } + }; + myEditor.getCaretModel().addCaretListener(caretListener); + myEditor.getSelectionModel().addSelectionListener(selectionListener); + ((DocumentEx)myEditor.getDocument()).setInBulkUpdate(true); + WriteCommandAction.runWriteCommandAction(ourProject, () -> {myEditor.getDocument().insertString(0, " ");}); + assertEquals("", output.toString()); + ((DocumentEx)myEditor.getDocument()).setInBulkUpdate(false); + myEditor.getSelectionModel().removeSelectionListener(selectionListener); + myEditor.getCaretModel().removeCaretListener(caretListener); + assertEquals("caret:LogicalPosition: (0, 7)selection:(4,7)", output.toString()); + checkResultByText(" abcdef"); + } }