Java Code Examples for com.intellij.util.text.CharArrayUtil#shiftBackward()

The following examples show how to use com.intellij.util.text.CharArrayUtil#shiftBackward() . You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example 1
Source File: ArrangementEntryWrapper.java    From consulo with Apache License 2.0 6 votes vote down vote up
@SuppressWarnings("AssignmentToForLoopParameter")
public void updateBlankLines(@Nonnull Document document) {
  int startLine = document.getLineNumber(getStartOffset());
  myBlankLinesBefore = 0;
  if (startLine <= 0) {
    return;
  }
  
  CharSequence text = document.getCharsSequence();
  int lastLineFeed = document.getLineStartOffset(startLine) - 1;
  for (int i = lastLineFeed - 1; i >= 0; i--) {
    i = CharArrayUtil.shiftBackward(text, i, " \t");
    if (text.charAt(i) == '\n') {
      ++myBlankLinesBefore;
    }
    else {
      break;
    }
  }
}
 
Example 2
Source File: ConsoleViewImpl.java    From consulo with Apache License 2.0 6 votes vote down vote up
private void addFoldRegion(@Nonnull Document document, @Nonnull ConsoleFolding folding, int startLine, int endLine) {
  List<String> toFold = new ArrayList<>(endLine - startLine + 1);
  for (int i = startLine; i <= endLine; i++) {
    toFold.add(EditorHyperlinkSupport.getLineText(document, i, false));
  }

  int oStart = document.getLineStartOffset(startLine);
  if (oStart > 0 && folding.shouldBeAttachedToThePreviousLine()) oStart--;
  int oEnd = CharArrayUtil.shiftBackward(document.getImmutableCharSequence(), document.getLineEndOffset(endLine) - 1, " \t") + 1;

  String placeholder = folding.getPlaceholderText(getProject(), toFold);
  FoldRegion region = placeholder == null ? null : myEditor.getFoldingModel().addFoldRegion(oStart, oEnd, placeholder);
  if (region != null) {
    region.setExpanded(false);
    region.putUserData(USED_FOLDING_KEY, folding);
  }
}
 
Example 3
Source File: OclCommenter.java    From reasonml-idea-plugin with MIT License 6 votes vote down vote up
@NotNull
private TextRange expandRange(@NotNull CharSequence chars, int delOffset1, int delOffset2) {
    int offset1 = CharArrayUtil.shiftBackward(chars, delOffset1 - 1, " \t");
    if (offset1 < 0 || chars.charAt(offset1) == '\n' || chars.charAt(offset1) == '\r') {
        int offset2 = CharArrayUtil.shiftForward(chars, delOffset2, " \t");
        if (offset2 == chars.length() || chars.charAt(offset2) == '\r' || chars.charAt(offset2) == '\n') {
            delOffset1 = (offset1 < 0) ? offset1 + 1 : offset1;
            if (offset2 < chars.length()) {
                delOffset2 = offset2 + 1;
                if (chars.charAt(offset2) == '\r' && offset2 + 1 < chars.length() && chars.charAt(offset2 + 1) == '\n') {
                    delOffset2++;
                }
            }
        }
    }
    return new TextRange(delOffset1, delOffset2);
}
 
Example 4
Source File: CommentByBlockCommentHandler.java    From consulo with Apache License 2.0 6 votes vote down vote up
private TextRange expandRange(int delOffset1, int delOffset2) {
  CharSequence chars = myDocument.getCharsSequence();
  int offset1 = CharArrayUtil.shiftBackward(chars, delOffset1 - 1, " \t");
  if (offset1 < 0 || chars.charAt(offset1) == '\n' || chars.charAt(offset1) == '\r') {
    int offset2 = CharArrayUtil.shiftForward(chars, delOffset2, " \t");
    if (offset2 == myDocument.getTextLength() || chars.charAt(offset2) == '\r' || chars.charAt(offset2) == '\n') {
      delOffset1 = offset1 + 1;
      if (offset2 < myDocument.getTextLength()) {
        delOffset2 = offset2 + 1;
        if (chars.charAt(offset2) == '\r' && offset2 + 1 < myDocument.getTextLength() && chars.charAt(offset2 + 1) == '\n') {
          delOffset2++;
        }
      }
    }
  }
  return new TextRange(delOffset1, delOffset2);
}
 
Example 5
Source File: IndexPatternSearcher.java    From consulo with Apache License 2.0 5 votes vote down vote up
private static List<TextRange> findContinuation(int mainRangeStartOffset, CharSequence text, IndexPattern[] allIndexPatterns, List<? extends CommentRange> commentRanges, int commentNum) {
  CommentRange commentRange = commentRanges.get(commentNum);
  int lineStartOffset = CharArrayUtil.shiftBackwardUntil(text, mainRangeStartOffset - 1, "\n") + 1;
  int lineEndOffset = CharArrayUtil.shiftForwardUntil(text, mainRangeStartOffset, "\n");
  int offsetInLine = mainRangeStartOffset - lineStartOffset;
  int maxCommentStartOffsetInLine = Math.max(0, commentRange.startOffset - lineStartOffset);
  List<TextRange> result = new ArrayList<>();
  outer:
  while (lineEndOffset < text.length()) {
    lineStartOffset = lineEndOffset + 1;
    lineEndOffset = CharArrayUtil.shiftForwardUntil(text, lineStartOffset, "\n");
    int refOffset = lineStartOffset + offsetInLine;
    int continuationStartOffset = CharArrayUtil.shiftForward(text, refOffset, lineEndOffset, WHITESPACE);
    if (continuationStartOffset == refOffset || continuationStartOffset >= lineEndOffset) break;
    if (continuationStartOffset >= commentRange.endOffset) {
      commentNum++;
      if (commentNum >= commentRanges.size()) break;
      commentRange = commentRanges.get(commentNum);
      if (continuationStartOffset < commentRange.startOffset || continuationStartOffset >= commentRange.endOffset) break;
    }
    int commentStartOffset = Math.max(lineStartOffset, commentRange.startOffset);
    int continuationEndOffset = Math.min(lineEndOffset, commentRange.endOffset);
    if (refOffset < commentStartOffset || commentStartOffset > lineStartOffset + maxCommentStartOffsetInLine ||
        CharArrayUtil.shiftBackward(text, commentStartOffset, refOffset - 1, WHITESPACE + commentRange.allowedContinuationPrefixChars) + 1 != commentStartOffset) {
      break;
    }
    CharSequence commentText = StringPattern.newBombedCharSequence(text.subSequence(commentStartOffset, continuationEndOffset));
    for (IndexPattern pattern : allIndexPatterns) {
      Pattern p = pattern.getPattern();
      if (p != null && p.matcher(commentText).find()) break outer;
    }
    result.add(new TextRange(continuationStartOffset, continuationEndOffset));
  }
  return result.isEmpty() ? Collections.emptyList() : result;
}
 
Example 6
Source File: FormattingRangesExtender.java    From consulo with Apache License 2.0 5 votes vote down vote up
@Nullable
private TextRange trimSpaces(@Nonnull TextRange range) {
  int startOffset = range.getStartOffset();
  int endOffset = range.getEndOffset();
  startOffset = CharArrayUtil.shiftForward(myDocument.getCharsSequence(), startOffset, endOffset, " /t");
  if (startOffset == endOffset) return null;
  endOffset = CharArrayUtil.shiftBackward(myDocument.getCharsSequence(), startOffset, endOffset, " /t");
  return new TextRange(startOffset, endOffset);
}
 
Example 7
Source File: CodeStyleManagerRunnable.java    From consulo with Apache License 2.0 5 votes vote down vote up
@Nonnull
private static TextRange extendRangeAtStartOffset(@Nonnull final PsiFile file, @Nonnull final TextRange range) {
  int startOffset = range.getStartOffset();
  if (startOffset > 0) {
    String text = file.getText();
    startOffset = CharArrayUtil.shiftBackward(text, startOffset, "\n\r\t ");
  }

  return new TextRange(startOffset + 1, range.getEndOffset());
}
 
Example 8
Source File: ExtendWordSelectionHandlerBase.java    From consulo with Apache License 2.0 5 votes vote down vote up
public static List<TextRange> expandToWholeLinesWithBlanks(CharSequence text, TextRange range) {
  List<TextRange> result = ContainerUtil.newArrayList();
  result.addAll(expandToWholeLine(text, range, true));

  TextRange last = result.isEmpty() ? range : result.get(result.size() - 1);
  int start = last.getStartOffset();
  int end = last.getEndOffset();
  while (true) {
    int blankLineEnd = CharArrayUtil.shiftForward(text, end, " \t");
    if (blankLineEnd >= text.length() || text.charAt(blankLineEnd) != '\n') {
      break;
    }
    end = blankLineEnd + 1;
  }
  if (end == last.getEndOffset()) {
    while (start > 0 && text.charAt(start - 1) == '\n') {
      int blankLineStart = CharArrayUtil.shiftBackward(text, start - 2, " \t");
      if (blankLineStart <= 0 || text.charAt(blankLineStart) != '\n') {
        break;
      }
      start = blankLineStart + 1;
    }
  }
  if (start != last.getStartOffset() || end != last.getEndOffset()) {
    result.add(new TextRange(start, end));
  }

  return result;
}
 
Example 9
Source File: CodeStyleManagerImpl.java    From consulo with Apache License 2.0 5 votes vote down vote up
@Override
@Deprecated
public boolean isLineToBeIndented(@Nonnull PsiFile file, int offset) {
  if (!SourceTreeToPsiMap.hasTreeElement(file)) {
    return false;
  }
  CharSequence chars = file.getViewProvider().getContents();
  int start = CharArrayUtil.shiftBackward(chars, offset - 1, " \t");
  if (start > 0 && chars.charAt(start) != '\n' && chars.charAt(start) != '\r') {
    return false;
  }
  int end = CharArrayUtil.shiftForward(chars, offset, " \t");
  if (end >= chars.length()) {
    return false;
  }
  ASTNode element = SourceTreeToPsiMap.psiElementToTree(findElementInTreeWithFormatterEnabled(file, end));
  if (element == null) {
    return false;
  }
  if (element.getElementType() == TokenType.WHITE_SPACE) {
    return false;
  }
  if (element.getElementType() == PlainTextTokenTypes.PLAIN_TEXT) {
    return false;
  }
  /*
  if( element.getElementType() instanceof IJspElementType )
  {
    return false;
  }
  */
  if (getSettings(file).getCommonSettings(file.getLanguage()).KEEP_FIRST_COLUMN_COMMENT && isCommentToken(element)) {
    if (IndentHelper.getInstance().getIndent(myProject, file.getFileType(), element, true) == 0) {
      return false;
    }
  }
  return true;
}
 
Example 10
Source File: TypedHandler.java    From consulo with Apache License 2.0 5 votes vote down vote up
private static boolean isTypingEscapeQuote(@Nonnull Editor editor, @Nonnull QuoteHandler quoteHandler, int offset) {
  if (offset == 0) return false;
  CharSequence chars = editor.getDocument().getCharsSequence();
  int offset1 = CharArrayUtil.shiftBackward(chars, offset - 1, "\\");
  int slashCount = offset - 1 - offset1;
  return slashCount % 2 != 0 && isInsideLiteral(editor, quoteHandler, offset);
}
 
Example 11
Source File: ParameterInfoController.java    From consulo with Apache License 2.0 4 votes vote down vote up
private static int getParameterNavigationOffset(@Nonnull PsiElement parameter, @Nonnull CharSequence text) {
  int rangeStart = parameter.getTextRange().getStartOffset();
  int rangeEnd = parameter.getTextRange().getEndOffset();
  int offset = CharArrayUtil.shiftBackward(text, rangeEnd - 1, WHITESPACE) + 1;
  return offset > rangeStart ? offset : CharArrayUtil.shiftForward(text, rangeEnd, WHITESPACE);
}
 
Example 12
Source File: FixDocCommentAction.java    From consulo with Apache License 2.0 4 votes vote down vote up
/**
 * Generates a comment if possible.
 * <p>
 * It's assumed that this method {@link PsiDocumentManager#commitDocument(Document) syncs} all PSI-document
 * changes during the processing.
 *
 * @param anchor    target element for which a comment should be generated
 * @param editor    target editor
 * @param commenter commenter to use
 * @param project   current project
 */
private static void generateComment(@Nonnull PsiElement anchor,
                                    @Nonnull Editor editor,
                                    @Nonnull CodeDocumentationProvider documentationProvider,
                                    @Nonnull CodeDocumentationAwareCommenter commenter,
                                    @Nonnull Project project) {
  Document document = editor.getDocument();
  int commentStartOffset = anchor.getTextRange().getStartOffset();
  int lineStartOffset = document.getLineStartOffset(document.getLineNumber(commentStartOffset));
  if (lineStartOffset > 0 && lineStartOffset < commentStartOffset) {
    // Example:
    //    void test1() {
    //    }
    //    void test2() {
    //       <offset>
    //    }
    // We want to insert the comment at the start of the line where 'test2()' is declared.
    int nonWhiteSpaceOffset = CharArrayUtil.shiftBackward(document.getCharsSequence(), commentStartOffset - 1, " \t");
    commentStartOffset = Math.max(nonWhiteSpaceOffset, lineStartOffset);
  }

  int commentBodyRelativeOffset = 0;
  int caretOffsetToSet = -1;
  StringBuilder buffer = new StringBuilder();
  String commentPrefix = commenter.getDocumentationCommentPrefix();
  if (commentPrefix != null) {
    buffer.append(commentPrefix).append("\n");
    commentBodyRelativeOffset += commentPrefix.length() + 1;
  }

  String linePrefix = commenter.getDocumentationCommentLinePrefix();
  if (linePrefix != null) {
    buffer.append(linePrefix);
    commentBodyRelativeOffset += linePrefix.length();
    caretOffsetToSet = commentStartOffset + commentBodyRelativeOffset;
  }
  buffer.append("\n");
  commentBodyRelativeOffset++;

  String commentSuffix = commenter.getDocumentationCommentSuffix();
  if (commentSuffix != null) {
    buffer.append(commentSuffix).append("\n");
  }

  if (buffer.length() <= 0) {
    return;
  }

  document.insertString(commentStartOffset, buffer);
  PsiDocumentManager docManager = PsiDocumentManager.getInstance(project);
  docManager.commitDocument(document);

  Pair<PsiElement, PsiComment> pair = documentationProvider.parseContext(anchor);
  if (pair == null || pair.second == null) {
    return;
  }

  String stub = documentationProvider.generateDocumentationContentStub(pair.second);
  CaretModel caretModel = editor.getCaretModel();
  if (stub != null) {
    int insertionOffset = commentStartOffset + commentBodyRelativeOffset;
    document.insertString(insertionOffset, stub);
    docManager.commitDocument(document);
    pair = documentationProvider.parseContext(anchor);
  }

  if (caretOffsetToSet >= 0) {
    caretModel.moveToOffset(caretOffsetToSet);
    editor.getSelectionModel().removeSelection();
  }

  if (pair == null || pair.second == null) {
    return;
  }

  int start = Math.min(calcStartReformatOffset(pair.first), calcStartReformatOffset(pair.second));
  int end = pair.second.getTextRange().getEndOffset();

  reformatCommentKeepingEmptyTags(anchor.getContainingFile(), project, start, end);
  editor.getCaretModel().moveToOffset(document.getLineEndOffset(document.getLineNumber(editor.getCaretModel().getOffset())));

  int caretOffset = caretModel.getOffset();
  if (caretOffset > 0 && caretOffset <= document.getTextLength()) {
    char c = document.getCharsSequence().charAt(caretOffset - 1);
    if (!StringUtil.isWhiteSpace(c)) {
      document.insertString(caretOffset, " ");
      caretModel.moveToOffset(caretOffset + 1);
    }
  }
}
 
Example 13
Source File: EndHandler.java    From consulo with Apache License 2.0 4 votes vote down vote up
@Override
protected void doExecute(@Nonnull final Editor editor, Caret caret, DataContext dataContext) {
  CodeInsightSettings settings = CodeInsightSettings.getInstance();
  if (!settings.SMART_END_ACTION) {
    if (myOriginalHandler != null) {
      myOriginalHandler.execute(editor, caret, dataContext);
    }
    return;
  }

  final Project project = DataManager.getInstance().getDataContext(editor.getComponent()).getData(CommonDataKeys.PROJECT);
  if (project == null) {
    if (myOriginalHandler != null) {
      myOriginalHandler.execute(editor, caret, dataContext);
    }
    return;
  }
  final Document document = editor.getDocument();
  final PsiFile file = PsiDocumentManager.getInstance(project).getPsiFile(document);

  if (file == null) {
    if (myOriginalHandler != null){
      myOriginalHandler.execute(editor, caret, dataContext);
    }
    return;
  }

  final EditorNavigationDelegate[] extensions = EditorNavigationDelegate.EP_NAME.getExtensions();
  for (EditorNavigationDelegate delegate : extensions) {
    if (delegate.navigateToLineEnd(editor, dataContext) == EditorNavigationDelegate.Result.STOP) {
      return;
    }
  }

  final CaretModel caretModel = editor.getCaretModel();
  final int caretOffset = caretModel.getOffset();
  CharSequence chars = editor.getDocument().getCharsSequence();
  int length = editor.getDocument().getTextLength();

  if (caretOffset < length) {
    final int offset1 = CharArrayUtil.shiftBackward(chars, caretOffset - 1, " \t");
    if (offset1 < 0 || chars.charAt(offset1) == '\n' || chars.charAt(offset1) == '\r') {
      final int offset2 = CharArrayUtil.shiftForward(chars, offset1 + 1, " \t");
      boolean isEmptyLine = offset2 >= length || chars.charAt(offset2) == '\n' || chars.charAt(offset2) == '\r';
      if (isEmptyLine) {

        // There is a possible case that indent string is not calculated for particular document (that is true at least for plain text
        // documents). Hence, we check that and don't finish processing in case we have such a situation.
        boolean stopProcessing = true;
        PsiDocumentManager.getInstance(project).commitAllDocuments();
        CodeStyleManager styleManager = CodeStyleManager.getInstance(project);
        final String lineIndent = styleManager.getLineIndent(file, caretOffset);
        if (lineIndent != null) {
          int col = calcColumnNumber(lineIndent, editor.getSettings().getTabSize(project));
          int line = caretModel.getVisualPosition().line;
          caretModel.moveToVisualPosition(new VisualPosition(line, col));

          if (caretModel.getLogicalPosition().column != col){
            if (!ApplicationManager.getApplication().isWriteAccessAllowed() &&
                !FileDocumentManager.getInstance().requestWriting(editor.getDocument(), project)) {
              return;
            }
            editor.getSelectionModel().removeSelection();
            WriteAction.run(() -> document.replaceString(offset1 + 1, offset2, lineIndent));
          }
        }
        else {
          stopProcessing = false;
        }

        editor.getScrollingModel().scrollToCaret(ScrollType.RELATIVE);
        editor.getSelectionModel().removeSelection();
        if (stopProcessing) {
          return;
        }
      }
    }
  }

  if (myOriginalHandler != null){
    myOriginalHandler.execute(editor, caret, dataContext);
  }
}
 
Example 14
Source File: ArrangementEngine.java    From consulo with Apache License 2.0 4 votes vote down vote up
@SuppressWarnings("AssignmentToForLoopParameter")
@Override
public void replace(@Nonnull ArrangementEntryWrapper<E> newWrapper,
                    @Nonnull ArrangementEntryWrapper<E> oldWrapper,
                    @Nullable ArrangementEntryWrapper<E> previous,
                    @Nullable ArrangementEntryWrapper<E> next,
                    @Nonnull Context<E> context)
{
  // Calculate blank lines before the arrangement.
  int blankLinesBefore = 0;
  TIntArrayList lineFeedOffsets = new TIntArrayList();
  int oldStartLine = context.document.getLineNumber(oldWrapper.getStartOffset());
  if (oldStartLine > 0) {
    int lastLineFeed = context.document.getLineStartOffset(oldStartLine) - 1;
    lineFeedOffsets.add(lastLineFeed);
    for (int i = lastLineFeed - 1 - myParentShift; i >= 0; i--) {
      i = CharArrayUtil.shiftBackward(myParentText, i, " \t");
      if (myParentText.charAt(i) == '\n') {
        blankLinesBefore++;
        lineFeedOffsets.add(i + myParentShift);
      }
      else {
        break;
      }
    }
  }

  ArrangementEntryWrapper<E> parentWrapper = oldWrapper.getParent();
  int desiredBlankLinesNumber = getBlankLines(context, parentWrapper, newWrapper, previous, next);
  if (desiredBlankLinesNumber == blankLinesBefore && newWrapper.equals(oldWrapper)) {
    return;
  }

  String newEntryText = myParentText.substring(newWrapper.getStartOffset() - myParentShift, newWrapper.getEndOffset() - myParentShift);
  int lineFeedsDiff = desiredBlankLinesNumber - blankLinesBefore;
  if (lineFeedsDiff == 0 || desiredBlankLinesNumber < 0) {
    context.addMoveInfo(newWrapper.getStartOffset() - myParentShift,
                        newWrapper.getEndOffset() - myParentShift,
                        oldWrapper.getStartOffset());
    context.document.replaceString(oldWrapper.getStartOffset(), oldWrapper.getEndOffset(), newEntryText);
    return;
  }

  if (lineFeedsDiff > 0) {
    // Insert necessary number of blank lines.
    StringBuilder buffer = new StringBuilder(StringUtil.repeat("\n", lineFeedsDiff));
    buffer.append(newEntryText);
    context.document.replaceString(oldWrapper.getStartOffset(), oldWrapper.getEndOffset(), buffer);
  }
  else {
    // Cut exceeding blank lines.
    int replacementStartOffset = lineFeedOffsets.get(-lineFeedsDiff) + 1;
    context.document.replaceString(replacementStartOffset, oldWrapper.getEndOffset(), newEntryText);
  }

  // Update wrapper ranges.
  ArrangementEntryWrapper<E> parent = oldWrapper.getParent();
  if (parent == null) {
    return;
  }

  Deque<ArrangementEntryWrapper<E>> parents = new ArrayDeque<ArrangementEntryWrapper<E>>();
  do {
    parents.add(parent);
    parent.setEndOffset(parent.getEndOffset() + lineFeedsDiff);
    parent = parent.getParent();
  }
  while (parent != null);


  while (!parents.isEmpty()) {

    for (ArrangementEntryWrapper<E> wrapper = parents.removeLast().getNext(); wrapper != null; wrapper = wrapper.getNext()) {
      wrapper.applyShift(lineFeedsDiff);
    }
  }
}
 
Example 15
Source File: EnterBetweenBracesHandler.java    From consulo with Apache License 2.0 4 votes vote down vote up
@Override
public Result preprocessEnter(@Nonnull final PsiFile file, @Nonnull final Editor editor, @Nonnull final Ref<Integer> caretOffsetRef, @Nonnull final Ref<Integer> caretAdvance,
                              @Nonnull final DataContext dataContext, final EditorActionHandler originalHandler) {
  Document document = editor.getDocument();
  CharSequence text = document.getCharsSequence();
  int caretOffset = caretOffsetRef.get().intValue();
  if (!CodeInsightSettings.getInstance().SMART_INDENT_ON_ENTER) {
    return Result.Continue;
  }

  int prevCharOffset = CharArrayUtil.shiftBackward(text, caretOffset - 1, " \t");
  int nextCharOffset = CharArrayUtil.shiftForward(text, caretOffset, " \t");

  if (!isValidOffset(prevCharOffset, text) || !isValidOffset(nextCharOffset, text) ||
      !isBracePair(text.charAt(prevCharOffset), text.charAt(nextCharOffset))) {
    return Result.Continue;
  }

  PsiDocumentManager.getInstance(file.getProject()).commitDocument(editor.getDocument());
  if (file.findElementAt(prevCharOffset) == file.findElementAt(nextCharOffset)) {
    return Result.Continue;
  }

  final int line = document.getLineNumber(caretOffset);
  final int start = document.getLineStartOffset(line);
  final CodeDocumentationUtil.CommentContext commentContext =
          CodeDocumentationUtil.tryParseCommentContext(file, text, caretOffset, start);

  // special case: enter inside "()" or "{}"
  String indentInsideJavadoc = isInComment(caretOffset, file) && commentContext.docAsterisk
                               ? CodeDocumentationUtil.getIndentInsideJavadoc(document, caretOffset)
                               : null;

  originalHandler.execute(editor, editor.getCaretModel().getCurrentCaret(), dataContext);

  Project project = editor.getProject();
  if (indentInsideJavadoc != null && project != null && CodeStyleSettingsManager.getSettings(project).JD_LEADING_ASTERISKS_ARE_ENABLED) {
    document.insertString(editor.getCaretModel().getOffset(), "*" + indentInsideJavadoc);
  }

  PsiDocumentManager.getInstance(file.getProject()).commitDocument(document);
  try {
    CodeStyleManager.getInstance(file.getProject()).adjustLineIndent(file, editor.getCaretModel().getOffset());
  }
  catch (IncorrectOperationException e) {
    LOG.error(e);
  }
  return indentInsideJavadoc == null ? Result.Continue : Result.DefaultForceIndent;
}
 
Example 16
Source File: SmartIndentingBackspaceHandler.java    From consulo with Apache License 2.0 4 votes vote down vote up
@Override
protected void doBeforeCharDeleted(char c, PsiFile file, Editor editor) {
  Project project = file.getProject();
  Document document = editor.getDocument();
  CharSequence charSequence = document.getImmutableCharSequence();
  CaretModel caretModel = editor.getCaretModel();
  int caretOffset = caretModel.getOffset();
  LogicalPosition pos = caretModel.getLogicalPosition();
  int lineStartOffset = document.getLineStartOffset(pos.line);
  int beforeWhitespaceOffset = CharArrayUtil.shiftBackward(charSequence, caretOffset - 1, " \t") + 1;
  if (beforeWhitespaceOffset != lineStartOffset) {
    myReplacement = null;
    return;
  }
  PsiDocumentManager.getInstance(project).commitDocument(document);
  CodeStyleFacade codeStyleFacade = CodeStyleFacade.getInstance(project);
  myReplacement = codeStyleFacade.getLineIndent(document, lineStartOffset);
  if (myReplacement == null) {
    return;
  }
  int tabSize = codeStyleFacade.getTabSize(file.getFileType());
  int targetColumn = getWidth(myReplacement, tabSize);
  int endOffset = CharArrayUtil.shiftForward(charSequence, caretOffset, " \t");
  LogicalPosition logicalPosition = caretOffset < endOffset ? editor.offsetToLogicalPosition(endOffset) : pos;
  int currentColumn = logicalPosition.column;
  if (currentColumn > targetColumn) {
    myStartOffset = lineStartOffset;
  }
  else if (logicalPosition.line == 0) {
    myStartOffset = 0;
    myReplacement = "";
  }
  else {
    int prevLineEndOffset = document.getLineEndOffset(logicalPosition.line - 1);
    myStartOffset = CharArrayUtil.shiftBackward(charSequence, prevLineEndOffset - 1, " \t") + 1;
    if (myStartOffset != document.getLineStartOffset(logicalPosition.line - 1)) {
      int spacing = CodeStyleManager.getInstance(project).getSpacing(file, endOffset);
      myReplacement = StringUtil.repeatSymbol(' ', Math.max(0, spacing));
    }
  }
}
 
Example 17
Source File: ParameterInfoController.java    From consulo with Apache License 2.0 4 votes vote down vote up
private int getCurrentOffset() {
  int caretOffset = myEditor.getCaretModel().getOffset();
  CharSequence chars = myEditor.getDocument().getCharsSequence();
  return myHandler.isWhitespaceSensitive() ? caretOffset : CharArrayUtil.shiftBackward(chars, caretOffset - 1, WHITESPACE) + 1;
}
 
Example 18
Source File: ArrangementUtil.java    From consulo with Apache License 2.0 4 votes vote down vote up
/**
 * Tries to build a text range on the given arguments basis. Expands to the line start/end if possible.
 * <p/>
 * This method is expected to be used in a situation when we want to arrange complete rows.
 * Example:
 * <pre>
 *   class Test {
 *        void test() {
 *        }
 *      int i;
 *   }
 * </pre>
 * Suppose, we want to locate fields before methods. We can move the exact field and method range then but indent will be broken,
 * i.e. we'll get the result below:
 * <pre>
 *   class Test {
 *        int i;
 *      void test() {
 *        }
 *   }
 * </pre>
 * We can expand field and method range to the whole lines and that would allow to achieve the desired result:
 * <pre>
 *   class Test {
 *      int i;
 *        void test() {
 *        }
 *   }
 * </pre>
 * However, this method is expected to just return given range if there are multiple distinct elements at the same line:
 * <pre>
 *   class Test {
 *     void test1(){} void test2() {} int i;
 *   }
 * </pre>
 *
 * @param initialRange  anchor range
 * @param document      target document against which the ranges are built
 * @return              expanded range if possible; <code>null</code> otherwise
 */
@Nonnull
public static TextRange expandToLineIfPossible(@Nonnull TextRange initialRange, @Nonnull Document document) {
  CharSequence text = document.getCharsSequence();
  String ws = " \t";

  int startLine = document.getLineNumber(initialRange.getStartOffset());
  int lineStartOffset = document.getLineStartOffset(startLine);
  int i = CharArrayUtil.shiftBackward(text, lineStartOffset + 1, initialRange.getStartOffset() - 1, ws);
  if (i != lineStartOffset) {
    return initialRange;
  }

  int endLine = document.getLineNumber(initialRange.getEndOffset());
  int lineEndOffset = document.getLineEndOffset(endLine);
  i = CharArrayUtil.shiftForward(text, initialRange.getEndOffset(), lineEndOffset, ws);

  return i == lineEndOffset ? TextRange.create(lineStartOffset, lineEndOffset) : initialRange;
}
 
Example 19
Source File: CodeFormatterFacade.java    From consulo with Apache License 2.0 4 votes vote down vote up
public void doWrapLongLinesIfNecessary(@Nonnull final Editor editor, @Nonnull final Project project, @Nonnull Document document,
                                       int startOffset, int endOffset, List<? extends TextRange> enabledRanges) {
  // Normalization.
  int startOffsetToUse = Math.min(document.getTextLength(), Math.max(0, startOffset));
  int endOffsetToUse = Math.min(document.getTextLength(), Math.max(0, endOffset));

  LineWrapPositionStrategy strategy = LanguageLineWrapPositionStrategy.INSTANCE.forEditor(editor);
  CharSequence text = document.getCharsSequence();
  int startLine = document.getLineNumber(startOffsetToUse);
  int endLine = document.getLineNumber(Math.max(0, endOffsetToUse - 1));
  int maxLine = Math.min(document.getLineCount(), endLine + 1);
  int tabSize = EditorUtil.getTabSize(editor);
  if (tabSize <= 0) {
    tabSize = 1;
  }
  int spaceSize = EditorUtil.getSpaceWidth(Font.PLAIN, editor);
  int[] shifts = new int[2];
  // shifts[0] - lines shift.
  // shift[1] - offset shift.
  int cumulativeShift = 0;

  for (int line = startLine; line < maxLine; line++) {
    int startLineOffset = document.getLineStartOffset(line);
    int endLineOffset = document.getLineEndOffset(line);
    if (!canWrapLine(Math.max(startOffsetToUse, startLineOffset), Math.min(endOffsetToUse, endLineOffset), cumulativeShift, enabledRanges)) {
      continue;
    }

    final int preferredWrapPosition = calculatePreferredWrapPosition(editor, text, tabSize, spaceSize, startLineOffset, endLineOffset, endOffsetToUse);

    if (preferredWrapPosition < 0 || preferredWrapPosition >= endLineOffset) {
      continue;
    }
    if (preferredWrapPosition >= endOffsetToUse) {
      return;
    }

    // We know that current line exceeds right margin if control flow reaches this place, so, wrap it.
    int wrapOffset =
            strategy.calculateWrapPosition(document, editor.getProject(), Math.max(startLineOffset, startOffsetToUse), Math.min(endLineOffset, endOffsetToUse), preferredWrapPosition, false, false);
    if (wrapOffset < 0 // No appropriate wrap position is found.
        // No point in splitting line when its left part contains only white spaces, example:
        //    line start -> |                   | <- right margin
        //                  |   aaaaaaaaaaaaaaaa|aaaaaaaaaaaaaaaaaaaa() <- don't want to wrap this line even if it exceeds right margin
        || CharArrayUtil.shiftBackward(text, startLineOffset, wrapOffset - 1, " \t") < startLineOffset) {
      continue;
    }

    // Move caret to the target position and emulate pressing <enter>.
    editor.getCaretModel().moveToOffset(wrapOffset);
    emulateEnter(editor, project, shifts);

    //If number of inserted symbols on new line after wrapping more or equal then symbols left on previous line
    //there was no point to wrapping it, so reverting to before wrapping version
    if (shifts[1] - 1 >= wrapOffset - startLineOffset) {
      document.deleteString(wrapOffset, wrapOffset + shifts[1]);
    }
    else {
      // We know that number of lines is just increased, hence, update the data accordingly.
      maxLine += shifts[0];
      endOffsetToUse += shifts[1];
      cumulativeShift += shifts[1];
    }

  }
}
 
Example 20
Source File: BuildEnterHandler.java    From intellij with Apache License 2.0 4 votes vote down vote up
private static boolean afterColon(Document doc, int offset) {
  CharSequence text = doc.getCharsSequence();
  int previousOffset = CharArrayUtil.shiftBackward(text, offset - 1, " \t");
  return text.charAt(previousOffset) == ':';
}