Example #1
0
  /** deletes the selected text */
  public void delete(final TextSelection selection) {
    final CursorPosition from = selection.from();
    final CursorPosition to = selection.to();

    final BlockToLineMapping fromMapping = findBlockFor(from.getLine());
    final int fromBlock = fromMapping.index;
    final int fromLine = fromMapping.line;
    final int fromCharacter = from.getCharacter();

    final BlockToLineMapping toMapping = findBlockFor(to.getLine());
    final int toBlock = toMapping.index;
    final int toLine = toMapping.line;
    final int toCharacter = to.getCharacter();

    if (fromBlock == toBlock) {
      final TextBlock block = (TextBlock) blocks.elementAt(fromBlock);
      block.delete(fromLine, fromCharacter, toLine, toCharacter);
    } else {
      TextBlock block = (TextBlock) blocks.elementAt(toBlock);
      block.deleteTo(toLine, toCharacter);

      block = (TextBlock) blocks.elementAt(fromBlock);
      block.deleteFrom(fromLine, fromCharacter);

      fromMapping.textBlock.join(toMapping.textBlock);
      blocks.removeElementAt(toMapping.index);

      for (int i = fromBlock + 1; i < toBlock; i++) {
        blocks.removeElementAt(i);
      }
    }
  }
  private static void assertBeforeCommit(
      Document document,
      PsiFile file,
      TextBlock textBlock,
      CharSequence chars,
      String oldPsiText,
      FileElement myTreeElementBeingReparsedSoItWontBeCollected) {
    int startOffset = textBlock.getStartOffset();
    int psiEndOffset = textBlock.getPsiEndOffset();
    if (oldPsiText != null) {
      @NonNls String msg = "PSI/document inconsistency before reparse: ";
      if (startOffset >= oldPsiText.length()) {
        msg += "startOffset=" + oldPsiText + " while text length is " + oldPsiText.length() + "; ";
        startOffset = oldPsiText.length();
      }

      String psiPrefix = oldPsiText.substring(0, startOffset);
      String docPrefix = chars.subSequence(0, startOffset).toString();
      String psiSuffix = oldPsiText.substring(psiEndOffset);
      String docSuffix = chars.subSequence(textBlock.getTextEndOffset(), chars.length()).toString();
      if (!psiPrefix.equals(docPrefix) || !psiSuffix.equals(docSuffix)) {
        if (!psiPrefix.equals(docPrefix)) {
          msg = msg + "psiPrefix=" + psiPrefix + "; docPrefix=" + docPrefix + ";";
        }
        if (!psiSuffix.equals(docSuffix)) {
          msg = msg + "psiSuffix=" + psiSuffix + "; docSuffix=" + docSuffix + ";";
        }
        throw new AssertionError(msg);
      }
    } else if (document.getTextLength() - textBlock.getTextEndOffset()
        != myTreeElementBeingReparsedSoItWontBeCollected.getTextLength() - psiEndOffset) {
      throw new AssertionError("PSI/document inconsistency before reparse: file=" + file);
    }
  }
Example #3
0
 public TextDocument clone() {
   final List<TextBlock> list = new ArrayList<TextBlock>(textBlocks.size());
   for (TextBlock tb : textBlocks) {
     list.add(tb.clone());
   }
   return new TextDocument(title, list);
 }
Example #4
0
 /**
  * Returns detailed debugging information about the contained {@link TextBlock}s.
  *
  * @return Debug information.
  */
 public String debugString() {
   StringBuilder sb = new StringBuilder();
   for (TextBlock tb : getTextBlocks()) {
     sb.append(tb.toString());
     sb.append('\n');
   }
   return sb.toString();
 }
Example #5
0
  private void insertLetterBeforeNonWord(TextBlock tb, char c) {
    TextBlock bpr = tb.previousTextBlock();
    if (bpr instanceof WordBlock) {
      insertLetterInWord(bpr, c, bpr.textLength());

    } else {
      addNewWordBlockAfter(bpr, c);
    }
  }
Example #6
0
 private void addNewPuncBlockAfter(TextBlock bpr, char c) {
   PunctuationBlock wb = new PunctuationBlock();
   wb.setText("" + c);
   Block bnx = bpr.next();
   bpr.setNext(wb);
   wb.setNext(bnx);
   caretBlock = wb;
   caretPos = 1;
 }
Example #7
0
  private void insertPuncBeforeNonPunc(TextBlock tb, char c) {
    TextBlock bpr = tb.previousTextBlock();
    if (bpr instanceof PunctuationBlock) {
      insertPuncInPunc(bpr, c, bpr.textLength());

    } else {
      addNewPuncBlockAfter(bpr, c);
    }
  }
  @Override
  public void drawU(UGraphic ug, double x, double y) {
    final StringBounder stringBounder = ug.getStringBounder();
    final double heightNum = numText.calculateDimension(stringBounder).getHeight();

    final double deltaY = calculateDimension(stringBounder).getHeight() - heightNum;

    numText.drawU(ug, x, y + deltaY / 2.0);
    super.drawU(ug, x + getNumberWithAndMargin(stringBounder), y);
  }
  @Override
  public void drawTOBEREMOVED(ColorMapper colorMapper, Graphics2D g2d, double x, double y) {
    final StringBounder stringBounder = StringBounderUtils.asStringBounder(g2d);
    final double heightNum = numText.calculateDimension(stringBounder).getHeight();

    final double deltaY = calculateDimension(stringBounder).getHeight() - heightNum;

    numText.drawTOBEREMOVED(colorMapper, g2d, x, y + deltaY / 2.0);
    super.drawTOBEREMOVED(colorMapper, g2d, x + getNumberWithAndMargin(stringBounder), y);
  }
 /**
  * Checks if the specified position intersects with a CPP comment.
  *
  * @param startLineNo the starting line number
  * @param startColNo the starting column number
  * @param endLineNo the ending line number
  * @param endColNo the ending column number
  * @return true if the positions intersects with a CPP comment.
  */
 private boolean hasIntersectionWithCppComment(
     int startLineNo, int startColNo, int endLineNo, int endColNo) {
   // Check CPP comments (line searching is possible)
   for (int lineNumber = startLineNo; lineNumber <= endLineNo; lineNumber++) {
     final TextBlock comment = cppComments.get(lineNumber);
     if (comment != null && comment.intersects(startLineNo, startColNo, endLineNo, endColNo)) {
       return true;
     }
   }
   return false;
 }
Example #11
0
 /**
  * returns the entire text of the content, with a newline between each block (but not after the
  * final block.
  */
 public String getText() {
   final StringBuffer content = new StringBuffer();
   final Enumeration e = blocks.elements();
   while (e.hasMoreElements()) {
     final TextBlock block = (TextBlock) e.nextElement();
     if (content.length() > 0) {
       content.append("\n");
     }
     content.append(block.getText());
   }
   return content.toString();
 }
 /**
  * Checks if the specified position intersects with a C comment.
  *
  * @param startLineNo the starting line number
  * @param startColNo the starting column number
  * @param endLineNo the ending line number
  * @param endColNo the ending column number
  * @return true if the positions intersects with a C comment.
  */
 private boolean hasIntersectionWithCComment(
     int startLineNo, int startColNo, int endLineNo, int endColNo) {
   // Check C comments (all comments should be checked)
   final Collection<List<TextBlock>> values = clangComments.values();
   for (final List<TextBlock> row : values) {
     for (final TextBlock comment : row) {
       if (comment.intersects(startLineNo, startColNo, endLineNo, endColNo)) {
         return true;
       }
     }
   }
   return false;
 }
Example #13
0
  public void deletBackwards() {
    if (caretPos == 0) {
      TextBlock tb = caretBlock.previousTextBlock();
      if (tb == null) {
        return;

      } else {
        caretBlock = tb;
        caretPos = caretBlock.textLength();
      }
    }

    if (caretBlock.textLength() == 1) {
      TextBlock tb = caretBlock.previousTextBlock();
      int newPos = tb.textLength();
      caretBlock.remove();
      if (tb == null) {
        caretBlock = textBoard.firstTextBlock();
        caretPos = 0;
      } else {
        caretBlock = tb;
        caretPos = newPos;
      }

    } else {
      caretBlock.deleteCharBefore(caretPos);
      caretPos -= 1;
    }

    textBoard.repaint();
  }
  @Override
  public void documentChanged(DocumentEvent event) {
    final Document document = event.getDocument();
    final FileViewProvider viewProvider = getCachedViewProvider(document);
    if (viewProvider == null) return;
    if (!isRelevant(viewProvider)) return;

    ApplicationManager.getApplication().assertWriteAccessAllowed();
    final List<PsiFile> files = viewProvider.getAllFiles();
    boolean commitNecessary = true;
    for (PsiFile file : files) {
      mySmartPointerManager.unfastenBelts(file, event.getOffset());

      final TextBlock textBlock = TextBlock.get(file);
      if (textBlock.isLocked()) {
        commitNecessary = false;
        continue;
      }

      textBlock.documentChanged(event);
      assert file instanceof PsiFileImpl
              || "mock.file".equals(file.getName())
                  && ApplicationManager.getApplication().isUnitTestMode()
          : event + "; file=" + file + "; allFiles=" + files + "; viewProvider=" + viewProvider;
    }

    boolean forceCommit =
        ApplicationManager.getApplication().hasWriteAction(ExternalChangeAction.class)
            && (SystemProperties.getBooleanProperty("idea.force.commit.on.external.change", false)
                || ApplicationManager.getApplication().isHeadlessEnvironment());

    // Consider that it's worth to perform complete re-parse instead of merge if the whole document
    // text is replaced and
    // current document lines number is roughly above 5000. This makes sense in situations when
    // external change is performed
    // for the huge file (that causes the whole document to be reloaded and 'merge' way takes a
    // while to complete).
    if (event.isWholeTextReplaced() && document.getTextLength() > 100000) {
      document.putUserData(BlockSupport.DO_NOT_REPARSE_INCREMENTALLY, Boolean.TRUE);
    }

    if (commitNecessary) {
      myUncommittedDocuments.add(document);
      if (forceCommit) {
        commitDocument(document);
      } else if (!((DocumentEx) document).isInBulkUpdate()) {
        myDocumentCommitProcessor.commitAsynchronously(myProject, document, event);
      }
    }
  }
Example #15
0
 private void insertPuncInNonPunc(TextBlock tb, char c, int cp) {
   PunctuationBlock wb = new PunctuationBlock();
   wb.setText("" + c);
   tb.insert(wb, cp);
   caretBlock = wb;
   caretPos = 1;
 }
Example #16
0
 private void insertLetterInNonWord(TextBlock tb, char c, int cp) {
   WordBlock wb = new WordBlock();
   wb.setText("" + c);
   tb.insert(wb, cp);
   caretBlock = wb;
   caretPos = 1;
 }
  @Override
  public void beforeDocumentChange(DocumentEvent event) {
    final Document document = event.getDocument();

    final FileViewProvider viewProvider = getCachedViewProvider(document);
    if (viewProvider == null) return;
    if (!isRelevant(viewProvider)) return;

    VirtualFile virtualFile = viewProvider.getVirtualFile();
    if (virtualFile.getFileType().isBinary()) return;

    final List<PsiFile> files = viewProvider.getAllFiles();
    PsiFile psiCause = null;
    for (PsiFile file : files) {
      mySmartPointerManager.fastenBelts(file, event.getOffset(), null);

      if (TextBlock.get(file).isLocked()) {
        psiCause = file;
      }
    }

    if (psiCause == null) {
      beforeDocumentChangeOnUnlockedDocument(viewProvider);
    }

    ((SingleRootFileViewProvider) viewProvider).beforeDocumentChanged(psiCause);
  }
Example #18
0
  @Override
  public Dimension2D calculateDimension(StringBounder stringBounder) {
    final double widthNum = getNumberWithAndMargin(stringBounder);
    final double heightNum = numText.calculateDimension(stringBounder).getHeight();

    final Dimension2D dim = super.calculateDimension(stringBounder);
    return new Dimension2DDouble(dim.getWidth() + widthNum, Math.max(heightNum, dim.getHeight()));
  }
Example #19
0
  public void caretRight() {
    if (caretBlock == null) {
      return;
    }
    if (caretPos < caretBlock.textLength()) {
      caretPos += 1;
    } else {
      TextBlock tb = caretBlock.nextTextBlock();
      if (tb == null) {

      } else {
        caretBlock = tb;
        caretPos = 1;
      }
    }
    textBoard.repaint();
  }
Example #20
0
 @Override
 public boolean apply(@Nullable Duplicate input) {
   if (input instanceof InnerDuplicate) {
     checkArgument(
         !original.equals(input.getTextBlock()),
         "TextBlock of an InnerDuplicate can not be the original TextBlock");
   }
   return true;
 }
Example #21
0
  private void insertPuncAfterNonPunc(TextBlock tb, char c) {
    TextBlock bnx = tb.nextTextBlock();
    if (bnx instanceof PunctuationBlock) {
      insertPuncInPunc(bnx, c, 0);

    } else {
      addNewPuncBlockAfter(tb, c);
    }
  }
Example #22
0
  public void caretLeft() {
    if (caretBlock == null) {
      return;
    }
    if (caretPos > 0) {
      caretPos -= 1;
    } else {
      TextBlock tb = caretBlock.previousTextBlock();
      if (tb == null) {

      } else {
        caretBlock = tb;
        caretPos = caretBlock.textLength() - 1;
      }
    }

    textBoard.repaint();
  }
Example #23
0
 /**
  * Returns the {@link TextDocument}'s content, non-content or both
  *
  * @param includeContent Whether to include TextBlocks marked as "content".
  * @param includeNonContent Whether to include TextBlocks marked as "non-content".
  * @return The text.
  */
 public String getText(boolean includeContent, boolean includeNonContent) {
   StringBuilder sb = new StringBuilder();
   LOOP:
   for (TextBlock block : getTextBlocks()) {
     if (block.isContent()) {
       if (!includeContent) {
         continue LOOP;
       }
     } else {
       if (!includeNonContent) {
         continue LOOP;
       }
     }
     sb.append(block.getText());
     sb.append('\n');
   }
   return sb.toString();
 }
Example #24
0
  private void insertLetterAfterNonWord(TextBlock tb, char c) {
    TextBlock bnx = tb.nextTextBlock();
    if (bnx instanceof WordBlock) {
      insertLetterInWord(bnx, c, 0);

    } else {
      addNewWordBlockAfter(tb, c);
    }
  }
Example #25
0
  private BlockToLineMapping findBlockFor(final int line) {
    if (line < 0) {
      throw new IllegalArgumentException("Line must be greater than, or equal to, zero: " + line);
    }

    int lineWithinBlock = line;
    for (int i = 0; i < blocks.size(); i++) {
      final TextBlock block = (TextBlock) blocks.elementAt(i);
      final int noLines = block.noLines();
      if (lineWithinBlock < noLines) {
        UI_LOG.debug("block " + i + ", line " + lineWithinBlock);
        return new BlockToLineMapping(i, block, lineWithinBlock);
      }
      lineWithinBlock -= noLines;
    }
    return null;
    // throw new IllegalArgumentException("line number not valid " + line);

  }
Example #26
0
 @Override
 public boolean equals(@Nullable Object o) {
   if (this == o) {
     return true;
   }
   if (o == null || getClass() != o.getClass()) {
     return false;
   }
   Duplication that = (Duplication) o;
   return original.equals(that.original) && duplicates.equals(that.duplicates);
 }
  private void doSync(
      @NotNull final PsiTreeChangeEvent event,
      boolean force,
      @NotNull final DocSyncAction syncAction) {
    if (!toProcessPsiEvent()) return;
    final PsiFile psiFile = event.getFile();
    if (psiFile == null || psiFile.getNode() == null) return;

    final DocumentEx document = (DocumentEx) myPsiDocumentManager.getCachedDocument(psiFile);
    if (document == null || document instanceof DocumentWindow) return;
    if (!force && getTransaction(document) == null) {
      return;
    }

    TextBlock textBlock = TextBlock.get(psiFile);

    if (!textBlock.isEmpty()) {
      throw new IllegalStateException("Attempt to modify PSI for non-committed Document!");
    }

    textBlock.performAtomically(
        new Runnable() {
          @Override
          public void run() {
            syncAction.syncDocument(document, (PsiTreeChangeEventImpl) event);
          }
        });

    final boolean insideTransaction = myTransactionsMap.containsKey(document);
    if (!insideTransaction) {
      document.setModificationStamp(psiFile.getViewProvider().getModificationStamp());
      if (LOG.isDebugEnabled()) {
        PsiDocumentManagerBase.checkConsistency(psiFile, document);
      }
    }

    psiFile.getViewProvider().contentsSynchronized();
  }
Example #28
0
  private void insertPunctuation(char c) {
    if (caretBlock instanceof PunctuationBlock) {
      insertPuncInPunc(caretBlock, c, caretPos);

    } else {
      if (caretPos == 0) {
        insertPuncBeforeNonPunc(caretBlock, c);

      } else if (caretPos == caretBlock.textLength()) {
        insertPuncAfterNonPunc(caretBlock, c);
      } else {
        insertPuncInNonPunc(caretBlock, c, caretPos);
      }
    }
  }
Example #29
0
  private void insertLetter(char c) {
    if (caretBlock instanceof WordBlock) {
      insertLetterInWord(caretBlock, c, caretPos);

    } else {
      if (caretPos == 0) {
        insertLetterBeforeNonWord(caretBlock, c);

      } else if (caretPos == caretBlock.textLength()) {
        insertLetterAfterNonWord(caretBlock, c);

      } else {
        insertLetterInNonWord(caretBlock, c, caretPos);
      }
    }
  }
Example #30
0
  private void newline() {
    if (caretPos == 0) {
      TextBlock tbp = caretBlock.previousTextBlock();
      if (tbp != null) {
        tbp.newlineAfter();
      }

    } else if (caretPos == caretBlock.textLength()) {
      caretBlock.newlineAfter();
      caretBlock = caretBlock.nextTextBlock();
      caretPos = 1;

    } else {
      caretBlock.insertNewline(caretPos);
      caretBlock = caretBlock.nextTextBlock();
      caretPos = 1;
    }
  }