EA-53866 - assert: CaretImpl.onBulkDocumentUpdateFinished

This commit is contained in:
Dmitry Batrak
2014-09-26 13:36:15 +04:00
parent 195ed45d8c
commit 24b3c8a73f
4 changed files with 30 additions and 15 deletions
@@ -722,4 +722,14 @@ public class FindManagerTest extends DaemonAnalyzerTestCase {
assertTrue(findResult.isStringFound());
assertTrue(findResult.getStartOffset() > prefix.length());
}
public void testNoExceptionDuringReplaceAll() {
configureByText(FileTypes.PLAIN_TEXT, "something\telse");
FindModel model = new FindModel();
model.setStringToFind("m");
model.setStringToReplace("M");
model.setPromptOnReplace(false);
FindUtil.replace(myProject, myEditor, 0, model);
assertEquals("soMething\telse", myEditor.getDocument().getText());
}
}
@@ -494,29 +494,23 @@ public class FindUtil {
document.startGuardedBlockChecking();
boolean toPrompt = model.isPromptOnReplace();
if (!toPrompt) {
((DocumentEx)document).setInBulkUpdate(true);
}
try {
toPrompt = doReplace(project, editor, model, document, offset, toPrompt, delegate);
doReplace(project, editor, model, document, offset, toPrompt, delegate);
}
catch (ReadOnlyFragmentModificationException e) {
EditorActionManager.getInstance().getReadonlyFragmentModificationHandler(document).handle(e);
}
finally {
if (!toPrompt) {
((DocumentEx)document).setInBulkUpdate(false);
}
document.stopGuardedBlockChecking();
}
return true;
}
private static boolean doReplace(Project project, final Editor editor, final FindModel aModel, final Document document, int caretOffset,
private static void doReplace(Project project, final Editor editor, final FindModel aModel, final Document document, int caretOffset,
boolean toPrompt, ReplaceDelegate delegate) {
FindManager findManager = FindManager.getInstance(project);
final FindModel model = (FindModel)aModel.clone();
final FindModel model = aModel.clone();
int occurrences = 0;
List<Pair<TextRange, String>> rangesToChange = new ArrayList<Pair<TextRange, String>>();
@@ -560,20 +554,18 @@ public class FindUtil {
}
if (promptResult == FindManager.PromptResult.ALL) {
toPrompt = false;
((DocumentEx)document).setInBulkUpdate(true);
}
}
int newOffset;
if (delegate == null || delegate.shouldReplace(result, toReplace)) {
boolean reallyReplace = toPrompt;
if (reallyReplace) {
if (toPrompt) {
//[SCR 7258]
if (!reallyReplaced) {
editor.getCaretModel().moveToOffset(0);
reallyReplaced = true;
}
}
TextRange textRange = doReplace(project, document, model, result, toReplace, reallyReplace, rangesToChange);
TextRange textRange = doReplace(project, document, model, result, toReplace, toPrompt, rangesToChange);
replaced = true;
newOffset = model.isForward() ? textRange.getEndOffset() : textRange.getStartOffset();
occurrences++;
@@ -646,7 +638,6 @@ public class FindUtil {
}
ReplaceInProjectManager.reportNumberReplacedOccurrences(project, occurrences);
return replaced;
}
@@ -853,6 +853,7 @@ public class CaretImpl extends UserDataHolderBase implements Caret {
void updateCaretPosition(@NotNull final DocumentEventImpl event) {
final DocumentEx document = myEditor.getDocument();
if (document.isInBulkUpdate()) return;
boolean performSoftWrapAdjustment = event.getNewLength() > 0 // We want to put caret just after the last added symbol
// There is a possible case that the user removes text just before the soft wrap. We want to keep caret
// on a visual line with soft wrap start then.
@@ -875,7 +876,6 @@ public class CaretImpl extends UserDataHolderBase implements Caret {
}
}
else {
if (document.isInBulkUpdate()) return;
int startOffset = event.getOffset();
int oldEndOffset = startOffset + event.getOldLength();
@@ -19,6 +19,7 @@ import com.intellij.codeInsight.folding.CodeFoldingManager;
import com.intellij.openapi.actionSystem.IdeActions;
import com.intellij.openapi.editor.Document;
import com.intellij.openapi.editor.VisualPosition;
import com.intellij.openapi.editor.ex.DocumentEx;
import com.intellij.testFramework.EditorTestUtil;
import java.io.IOException;
@@ -89,6 +90,19 @@ public class EditorImplTest extends AbstractEditorTest {
checkResultByText(" \t<caret>space-indented line");
}
public void testNoExceptionDuringBulkModeDocumentUpdate() throws Exception {
init("something");
DocumentEx document = (DocumentEx)myEditor.getDocument();
document.setInBulkUpdate(true);
try {
document.setText("something\telse");
}
finally {
document.setInBulkUpdate(false);
}
checkResultByText("something\telse");
}
private void init(String text) throws IOException {
configureFromFileText(getTestName(false) + ".txt", text);
}