private static void doCommitTransaction( @NotNull Document document, @NotNull DocumentChangeTransaction documentChangeTransaction) { DocumentEx ex = (DocumentEx) document; ex.suppressGuardedExceptions(); try { boolean isReadOnly = !document.isWritable(); ex.setReadOnly(false); final Set<Pair<MutableTextRange, StringBuffer>> affectedFragments = documentChangeTransaction.getAffectedFragments(); for (final Pair<MutableTextRange, StringBuffer> pair : affectedFragments) { final StringBuffer replaceBuffer = pair.getSecond(); final MutableTextRange range = pair.getFirst(); if (replaceBuffer.length() == 0) { ex.deleteString(range.getStartOffset(), range.getEndOffset()); } else if (range.getLength() == 0) { ex.insertString(range.getStartOffset(), replaceBuffer); } else { ex.replaceString(range.getStartOffset(), range.getEndOffset(), replaceBuffer); } } ex.setReadOnly(isReadOnly); // if(documentChangeTransaction.getChangeScope() != null) { // // LOG.assertTrue(document.getText().equals(documentChangeTransaction.getChangeScope().getText()), // "Psi to document synchronization failed (send to IK)"); // } } finally { ex.unSuppressGuardedExceptions(); } }
public void testUpdatingCaretPositionAfterBulkMode() throws Exception { initText("a<caret>bc"); DocumentEx document = (DocumentEx) myEditor.getDocument(); document.setInBulkUpdate(true); document.insertString( 0, "\n "); // we're changing number of visual lines, and invalidating text layout for caret // line document.setInBulkUpdate(false); checkResultByText("\n a<caret>bc"); }
@Override public void insertString(final int offset, @NotNull CharSequence s) { synchronized (myLock) { LOG.assertTrue(offset >= myShreds.get(0).getPrefix().length(), myShreds.get(0).getPrefix()); LOG.assertTrue( offset <= getTextLength() - myShreds.get(myShreds.size() - 1).getSuffix().length(), myShreds.get(myShreds.size() - 1).getSuffix()); } if (isOneLine()) { s = StringUtil.replace(s.toString(), "\n", ""); } myDelegate.insertString(injectedToHost(offset), s); }
@SuppressWarnings("AssignmentToForLoopParameter") @Override public void replace( @NotNull ArrangementEntryWrapper<E> newWrapper, @NotNull ArrangementEntryWrapper<E> oldWrapper, @Nullable ArrangementEntryWrapper<E> previous, @NotNull Context<E> context) { // Calculate blank lines before the arrangement. int blankLinesBefore = oldWrapper.getBlankLinesBefore(); ArrangementEntryWrapper<E> parentWrapper = oldWrapper.getParent(); int desiredBlankLinesNumber = context.rearranger.getBlankLines( context.settings, parentWrapper == null ? null : parentWrapper.getEntry(), previous == null ? null : previous.getEntry(), newWrapper.getEntry()); if ((desiredBlankLinesNumber < 0 || desiredBlankLinesNumber == blankLinesBefore) && newWrapper.equals(oldWrapper)) { return; } int lineFeedsDiff = desiredBlankLinesNumber - blankLinesBefore; int insertionOffset = oldWrapper.getStartOffset(); if (oldWrapper.getStartOffset() > newWrapper.getStartOffset()) { insertionOffset -= newWrapper.getEndOffset() - newWrapper.getStartOffset(); } if (newWrapper.getStartOffset() != oldWrapper.getStartOffset() || !newWrapper.equals(oldWrapper)) { context.addMoveInfo( newWrapper.getStartOffset(), newWrapper.getEndOffset(), oldWrapper.getStartOffset()); myDocument.moveText( newWrapper.getStartOffset(), newWrapper.getEndOffset(), oldWrapper.getStartOffset()); for (int i = myWrappers.size() - 1; i >= 0; i--) { ArrangementEntryWrapper<E> w = myWrappers.get(i); if (w == newWrapper) { continue; } if (w.getStartOffset() >= oldWrapper.getStartOffset() && w.getStartOffset() < newWrapper.getStartOffset()) { w.applyShift(newWrapper.getEndOffset() - newWrapper.getStartOffset()); } else if (w.getStartOffset() < oldWrapper.getStartOffset() && w.getStartOffset() > newWrapper.getStartOffset()) { w.applyShift(newWrapper.getStartOffset() - newWrapper.getEndOffset()); } } } if (desiredBlankLinesNumber >= 0 && lineFeedsDiff > 0) { myDocument.insertString(insertionOffset, StringUtil.repeat("\n", lineFeedsDiff)); shiftOffsets(lineFeedsDiff, insertionOffset); } if (desiredBlankLinesNumber >= 0 && lineFeedsDiff < 0) { // Cut exceeding blank lines. int replacementStartOffset = getBlankLineOffset(-lineFeedsDiff, insertionOffset); myDocument.deleteString(replacementStartOffset, insertionOffset); shiftOffsets(replacementStartOffset - insertionOffset, insertionOffset); } // Update wrapper ranges. if (desiredBlankLinesNumber < 0 || lineFeedsDiff == 0 || parentWrapper == null) { return; } Deque<ArrangementEntryWrapper<E>> parents = new ArrayDeque<ArrangementEntryWrapper<E>>(); do { parents.add(parentWrapper); parentWrapper.setEndOffset(parentWrapper.getEndOffset() + lineFeedsDiff); parentWrapper = parentWrapper.getParent(); } while (parentWrapper != null); while (!parents.isEmpty()) { for (ArrangementEntryWrapper<E> wrapper = parents.removeLast().getNext(); wrapper != null; wrapper = wrapper.getNext()) { wrapper.applyShift(lineFeedsDiff); } } }