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 testNested3() {
    RangeMarker marker1 = createMarker("01[23]4567890123");
    DocumentEx document = (DocumentEx) marker1.getDocument();
    RangeMarker marker2 = document.createRangeMarker(9, 11);
    RangeMarker marker3 = document.createRangeMarker(1, 12);
    marker3.dispose();

    document.deleteString(marker1.getEndOffset(), marker2.getStartOffset());
  }
  public void testLL() {
    RangeMarker marker1 = createMarker("012345678901234567", 5, 6);
    DocumentEx document = (DocumentEx) marker1.getDocument();
    document.createRangeMarker(4, 5);
    document.createRangeMarker(6, 7);
    document.createRangeMarker(0, 4);
    document.deleteString(1, 2);

    document.createRangeMarker(0, 7);
    document.createRangeMarker(0, 7);
  }
 public void testBranched() {
   RangeMarker marker1 = createMarker("01234567890123456", 0, 1);
   DocumentEx document = (DocumentEx) marker1.getDocument();
   RangeMarker marker2 = document.createRangeMarker(2, 3);
   RangeMarker marker3 = document.createRangeMarker(4, 5);
   RangeMarker marker4 = document.createRangeMarker(6, 7);
   RangeMarker marker5 = document.createRangeMarker(8, 9);
   RangeMarker marker6 = document.createRangeMarker(10, 11);
   RangeMarker marker7 = document.createRangeMarker(12, 13);
   RangeMarker marker8 = document.createRangeMarker(14, 15);
   document.deleteString(1, 2);
 }
  @Override
  public void deleteString(final int startOffset, final int endOffset) {
    assert intersectWithEditable(new TextRange(startOffset, startOffset)) != null;
    assert intersectWithEditable(new TextRange(endOffset, endOffset)) != null;

    List<TextRange> hostRangesToDelete;
    synchronized (myLock) {
      hostRangesToDelete = new ArrayList<TextRange>(myShreds.size());

      int offset = startOffset;
      int curRangeStart = 0;
      for (PsiLanguageInjectionHost.Shred shred : myShreds) {
        curRangeStart += shred.getPrefix().length();
        if (offset < curRangeStart) offset = curRangeStart;
        if (offset >= endOffset) break;
        Segment hostRange = shred.getHostRangeMarker();
        if (hostRange == null) continue;
        int hostRangeLength = hostRange.getEndOffset() - hostRange.getStartOffset();
        TextRange range = TextRange.from(curRangeStart, hostRangeLength);
        if (range.contains(offset)) {
          TextRange rangeToDelete =
              new TextRange(offset, Math.min(range.getEndOffset(), endOffset));
          hostRangesToDelete.add(
              rangeToDelete.shiftRight(hostRange.getStartOffset() - curRangeStart));
          offset = rangeToDelete.getEndOffset();
        }
        curRangeStart += hostRangeLength;
        curRangeStart += shred.getSuffix().length();
      }
    }

    int delta = 0;
    for (TextRange hostRangeToDelete : hostRangesToDelete) {
      myDelegate.deleteString(
          hostRangeToDelete.getStartOffset() + delta, hostRangeToDelete.getEndOffset() + delta);
      delta -= hostRangeToDelete.getLength();
    }
  }
예제 #6
0
    @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);
        }
      }
    }
 public void testDevourMarkerWithDeletion() {
   RangeMarker marker1 = createMarker("012345[67890123456]7");
   DocumentEx document = (DocumentEx) marker1.getDocument();
   document.deleteString(1, document.getTextLength());
 }