protected void moveCaretInsideBracesIfAny(
      @NotNull final Editor editor, @NotNull final PsiFile file)
      throws IncorrectOperationException {
    int caretOffset = editor.getCaretModel().getOffset();
    final CharSequence chars = editor.getDocument().getCharsSequence();

    if (CharArrayUtil.regionMatches(chars, caretOffset, "{}")) {
      caretOffset += 2;
    } else if (CharArrayUtil.regionMatches(chars, caretOffset, "{\n}")) {
      caretOffset += 3;
    }

    caretOffset = CharArrayUtil.shiftBackward(chars, caretOffset - 1, " \t") + 1;

    if (CharArrayUtil.regionMatches(chars, caretOffset - "{}".length(), "{}")
        || CharArrayUtil.regionMatches(chars, caretOffset - "{\n}".length(), "{\n}")) {
      commit(editor);
      final CodeStyleSettings settings = CodeStyleSettingsManager.getSettings(file.getProject());
      final boolean old = settings.KEEP_SIMPLE_BLOCKS_IN_ONE_LINE;
      settings.KEEP_SIMPLE_BLOCKS_IN_ONE_LINE = false;
      PsiElement elt =
          PsiTreeUtil.getParentOfType(file.findElementAt(caretOffset - 1), PsiCodeBlock.class);
      reformat(elt);
      settings.KEEP_SIMPLE_BLOCKS_IN_ONE_LINE = old;
      editor.getCaretModel().moveToOffset(caretOffset - 1);
    }
  }
Пример #2
0
 private boolean needToShiftWhiteSpaces(final DocumentEvent e) {
   if (!CharArrayUtil.containsOnlyWhiteSpaces(e.getNewFragment())
       || CharArrayUtil.containLineBreaks(e.getNewFragment())) return e.getOldLength() > 0;
   if (e.getOffset() == 0) return false;
   final char charBefore = myEditor.getDocument().getCharsSequence().charAt(e.getOffset() - 1);
   // final char charAfter = myEditor.getDocument().getCharsSequence().charAt(e.getOffset() +
   // e.getNewLength());
   return Character.isWhitespace(charBefore) /* || !Character.isWhitespace(charAfter)*/;
 }
 private int getCommentStart(int line) {
   int offset = myDocument.getLineStartOffset(line);
   CharSequence chars = myDocument.getCharsSequence();
   offset = CharArrayUtil.shiftForward(chars, offset, " \t");
   final Commenter commenter = findCommenter(line);
   if (commenter == null) return -1;
   String prefix = commenter.getLineCommentPrefix();
   if (prefix == null) prefix = commenter.getBlockCommentPrefix();
   if (prefix == null) return -1;
   return CharArrayUtil.regionMatches(chars, offset, prefix) ? offset : -1;
 }
Пример #4
0
  @SuppressWarnings("ForLoopThatDoesntUseLoopVariable")
  private static void indentPlainTextBlock(
      final Document document, final int startOffset, final int endOffset, final int indentLevel) {
    CharSequence chars = document.getCharsSequence();
    int spaceEnd = CharArrayUtil.shiftForward(chars, startOffset, " \t");
    int line = document.getLineNumber(startOffset);
    if (spaceEnd > endOffset
        || indentLevel <= 0
        || line >= document.getLineCount() - 1
        || chars.charAt(spaceEnd) == '\n') {
      return;
    }

    int linesToAdjustIndent = 0;
    for (int i = line + 1; i < document.getLineCount(); i++) {
      if (document.getLineStartOffset(i) >= endOffset) {
        break;
      }
      linesToAdjustIndent++;
    }

    String indentString = StringUtil.repeatSymbol(' ', indentLevel);

    for (; linesToAdjustIndent > 0; linesToAdjustIndent--) {
      int lineStartOffset = document.getLineStartOffset(++line);
      document.insertString(lineStartOffset, indentString);
    }
  }
Пример #5
0
 public int copyTo(@Nullable char[] buffer, int start) {
   final int length = myText.length();
   if (buffer != null) {
     CharArrayUtil.getChars(myText, buffer, start, length);
   }
   return start + length;
 }
Пример #6
0
 @Override
 @NotNull
 public char[] textToCharArray() {
   final char[] buffer = new char[myText.length()];
   CharArrayUtil.getChars(myText, buffer, 0);
   return buffer;
 }
 @Nullable
 private TextRange getSelectedComments(CharSequence text, String prefix, String suffix) {
   TextRange commentedRange = null;
   if (myCaret.hasSelection()) {
     int selectionStart = myCaret.getSelectionStart();
     selectionStart = CharArrayUtil.shiftForward(text, selectionStart, " \t\n");
     int selectionEnd = myCaret.getSelectionEnd() - 1;
     selectionEnd = CharArrayUtil.shiftBackward(text, selectionEnd, " \t\n") + 1;
     if (selectionEnd - selectionStart >= prefix.length() + suffix.length()
         && CharArrayUtil.regionMatches(text, selectionStart, prefix)
         && CharArrayUtil.regionMatches(text, selectionEnd - suffix.length(), suffix)) {
       commentedRange = new TextRange(selectionStart, selectionEnd);
     }
   }
   return commentedRange;
 }
  private int getPrevOrNextParameterOffset(boolean isNext) {
    if (!(myHandler instanceof ParameterInfoHandlerWithTabActionSupport)) return -1;
    ParameterInfoHandlerWithTabActionSupport handler =
        (ParameterInfoHandlerWithTabActionSupport) myHandler;

    boolean noDelimiter = handler.getActualParameterDelimiterType() == TokenType.WHITE_SPACE;
    int caretOffset = myEditor.getCaretModel().getOffset();
    int offset =
        noDelimiter
            ? caretOffset
            : CharArrayUtil.shiftBackward(
                    myEditor.getDocument().getCharsSequence(), caretOffset - 1, " \t")
                + 1;
    int lbraceOffset = myLbraceMarker.getStartOffset();
    PsiFile file = PsiDocumentManager.getInstance(myProject).getPsiFile(myEditor.getDocument());
    PsiElement argList =
        lbraceOffset < offset ? findArgumentList(file, offset, lbraceOffset) : null;
    if (argList == null) return -1;

    @SuppressWarnings("unchecked")
    PsiElement[] parameters = handler.getActualParameters(argList);
    int currentParameterIndex =
        noDelimiter
            ? JBIterable.of(parameters).indexOf((o) -> o.getTextRange().containsOffset(offset))
            : ParameterInfoUtils.getCurrentParameterIndex(
                argList.getNode(), offset, handler.getActualParameterDelimiterType());

    int prevOrNextParameterIndex =
        isNext && currentParameterIndex < parameters.length - 1
            ? currentParameterIndex + 1
            : !isNext && currentParameterIndex > 0 ? currentParameterIndex - 1 : -1;
    return prevOrNextParameterIndex != -1
        ? parameters[prevOrNextParameterIndex].getTextRange().getStartOffset()
        : -1;
  }
Пример #9
0
 /**
  * Tries to calculate given line's indent column assuming that there might be a comment at the
  * given indent offset (see {@link #getCommentPrefix(IElementType)}).
  *
  * @param line target line
  * @param indentOffset start indent offset to use for the given line
  * @param lineEndOffset given line's end offset
  * @param fallbackColumn column to return if it's not possible to apply comment-specific indent
  *     calculation rules
  * @return given line's indent column to use
  */
 private int calcIndent(int line, int indentOffset, int lineEndOffset, int fallbackColumn) {
   final HighlighterIterator it = myEditor.getHighlighter().createIterator(indentOffset);
   IElementType tokenType = it.getTokenType();
   Language language = tokenType.getLanguage();
   TokenSet comments = myComments.get(language);
   if (comments == null) {
     ParserDefinition definition = LanguageParserDefinitions.INSTANCE.forLanguage(language);
     if (definition != null) {
       comments = definition.getCommentTokens();
     }
     if (comments == null) {
       return fallbackColumn;
     } else {
       myComments.put(language, comments);
     }
   }
   if (comments.contains(tokenType) && indentOffset == it.getStart()) {
     String prefix = COMMENT_PREFIXES.get(tokenType);
     if (prefix == null) {
       prefix = getCommentPrefix(tokenType);
     }
     if (!NO_COMMENT_INFO_MARKER.equals(prefix)) {
       final int indentInsideCommentOffset =
           CharArrayUtil.shiftForward(
               myChars, indentOffset + prefix.length(), lineEndOffset, " \t");
       if (indentInsideCommentOffset < lineEndOffset) {
         int indent = myEditor.calcColumnNumber(indentInsideCommentOffset, line);
         indentAfterUncomment.put(line, indent - prefix.length());
         return indent;
       }
     }
   }
   return fallbackColumn;
 }
  private void altCommitToOriginal(@NotNull DocumentEvent e) {
    final PsiFile origPsiFile =
        PsiDocumentManager.getInstance(myProject).getPsiFile(myOrigDocument);
    String newText = myNewDocument.getText();
    // prepare guarded blocks
    LinkedHashMap<String, String> replacementMap = new LinkedHashMap<String, String>();
    int count = 0;
    for (RangeMarker o : ContainerUtil.reverse(((DocumentEx) myNewDocument).getGuardedBlocks())) {
      String replacement = o.getUserData(REPLACEMENT_KEY);
      String tempText = "REPLACE" + (count++) + Long.toHexString(StringHash.calc(replacement));
      newText =
          newText.substring(0, o.getStartOffset()) + tempText + newText.substring(o.getEndOffset());
      replacementMap.put(tempText, replacement);
    }
    // run preformat processors
    final int hostStartOffset = myAltFullRange.getStartOffset();
    myEditor.getCaretModel().moveToOffset(hostStartOffset);
    for (CopyPastePreProcessor preProcessor :
        Extensions.getExtensions(CopyPastePreProcessor.EP_NAME)) {
      newText = preProcessor.preprocessOnPaste(myProject, origPsiFile, myEditor, newText, null);
    }
    myOrigDocument.replaceString(hostStartOffset, myAltFullRange.getEndOffset(), newText);
    // replace temp strings for guarded blocks
    for (String tempText : replacementMap.keySet()) {
      int idx =
          CharArrayUtil.indexOf(
              myOrigDocument.getCharsSequence(),
              tempText,
              hostStartOffset,
              myAltFullRange.getEndOffset());
      myOrigDocument.replaceString(idx, idx + tempText.length(), replacementMap.get(tempText));
    }
    // JAVA: fix occasional char literal concatenation
    fixDocumentQuotes(myOrigDocument, hostStartOffset - 1);
    fixDocumentQuotes(myOrigDocument, myAltFullRange.getEndOffset());

    // reformat
    PsiDocumentManager.getInstance(myProject).commitDocument(myOrigDocument);
    Runnable task =
        () -> {
          try {
            CodeStyleManager.getInstance(myProject)
                .reformatRange(origPsiFile, hostStartOffset, myAltFullRange.getEndOffset(), true);
          } catch (IncorrectOperationException e1) {
            // LOG.error(e);
          }
        };
    DocumentUtil.executeInBulk(myOrigDocument, true, task);

    PsiElement newInjected =
        InjectedLanguageManager.getInstance(myProject)
            .findInjectedElementAt(origPsiFile, hostStartOffset);
    DocumentWindow documentWindow =
        newInjected == null ? null : InjectedLanguageUtil.getDocumentWindow(newInjected);
    if (documentWindow != null) {
      myEditor.getCaretModel().moveToOffset(documentWindow.injectedToHost(e.getOffset()));
      myEditor.getScrollingModel().scrollToCaret(ScrollType.MAKE_VISIBLE);
    }
  }
Пример #11
0
  @NotNull
  private static Pair<CharSequence, String> convertLineSeparators(@NotNull CharBuffer buffer) {
    int dst = 0;
    char prev = ' ';
    int crCount = 0;
    int lfCount = 0;
    int crlfCount = 0;

    final int length = buffer.length();
    final char[] bufferArray = CharArrayUtil.fromSequenceWithoutCopying(buffer);

    for (int src = 0; src < length; src++) {
      char c = bufferArray != null ? bufferArray[src] : buffer.charAt(src);
      switch (c) {
        case '\r':
          if (bufferArray != null) bufferArray[dst++] = '\n';
          else buffer.put(dst++, '\n');
          crCount++;
          break;
        case '\n':
          if (prev == '\r') {
            crCount--;
            crlfCount++;
          } else {
            if (bufferArray != null) bufferArray[dst++] = '\n';
            else buffer.put(dst++, '\n');
            lfCount++;
          }
          break;
        default:
          if (bufferArray != null) bufferArray[dst++] = c;
          else buffer.put(dst++, c);
          break;
      }
      prev = c;
    }

    String detectedLineSeparator = null;
    if (crlfCount > crCount && crlfCount > lfCount) {
      detectedLineSeparator = "\r\n";
    } else if (crCount > lfCount) {
      detectedLineSeparator = "\r";
    } else if (lfCount > 0) {
      detectedLineSeparator = "\n";
    }

    CharSequence result;
    if (buffer.length() == dst) {
      result = buffer;
    } else {
      // in Mac JDK CharBuffer.subSequence() signature differs from Oracle's
      // more than that, the signature has changed between jd6 and jdk7,
      // so use more generic CharSequence.subSequence() just in case
      @SuppressWarnings("UnnecessaryLocalVariable")
      CharSequence seq = buffer;
      result = seq.subSequence(0, dst);
    }
    return Pair.create(result, detectedLineSeparator);
  }
Пример #12
0
 private void prepareForModification() {
   if (myOriginalSequence != null) {
     myArray = new char[myOriginalSequence.length()];
     CharArrayUtil.getChars(myOriginalSequence, myArray, 0);
     myOriginalSequence = null;
   }
   myStringRef = null;
 }
Пример #13
0
  public int copyTo(@Nullable char[] buffer, int start) {
    CharSequence text = myText();
    if (text == null) return -1;

    if (buffer != null) {
      CharArrayUtil.getChars(text, buffer, start);
    }
    return start + text.length();
  }
  @Nullable
  private Commenter findCommenter(final int line) {
    final FileType fileType = myFile.getFileType();
    if (fileType instanceof AbstractFileType) {
      return ((AbstractFileType) fileType).getCommenter();
    }

    int lineStartOffset = myDocument.getLineStartOffset(line);
    int lineEndOffset = myDocument.getLineEndOffset(line) - 1;
    final CharSequence charSequence = myDocument.getCharsSequence();
    lineStartOffset = CharArrayUtil.shiftForward(charSequence, lineStartOffset, " \t");
    lineEndOffset =
        CharArrayUtil.shiftBackward(charSequence, lineEndOffset < 0 ? 0 : lineEndOffset, " \t");
    final Language lineStartLanguage = PsiUtilBase.getLanguageAtOffset(myFile, lineStartOffset);
    final Language lineEndLanguage = PsiUtilBase.getLanguageAtOffset(myFile, lineEndOffset);
    return CommentByBlockCommentHandler.getCommenter(
        myFile, myEditor, lineStartLanguage, lineEndLanguage);
  }
    protected final void locateToken() {
      if (myTokenType != null) return;
      _locateToken();

      if (myTokenType == ScalaDocTokenType.DOC_WHITESPACE) {
        myAfterLineBreak =
            CharArrayUtil.containLineBreaks(myBuffer, getTokenStart(), getTokenEnd());
      }
    }
Пример #16
0
  private boolean isSingleLineChange(
      @NotNull CharSequence prevText, int start, int end, @NotNull CharSequence replacement) {
    if (start == 0 && end == myLength && replacement.length() == 0) return false;

    int startLine = findLineIndex(start);
    return startLine == findLineIndex(end)
        && !CharArrayUtil.containLineBreaks(replacement)
        && !isLastEmptyLine(startLine);
  }
Пример #17
0
 public void reset(CharSequence buffer, int start, int end, int initialState) {
   zzBuffer = buffer;
   zzBufferArray = com.intellij.util.text.CharArrayUtil.fromSequenceWithoutCopying(buffer);
   zzCurrentPos = zzMarkedPos = zzStartRead = start;
   zzPushbackPos = 0;
   zzAtEOF = false;
   zzAtBOL = true;
   zzEndRead = end;
   yybegin(initialState);
 }
 /**
  * Current handler inserts closing curly brace (right brace) if necessary. There is a possible
  * case that it should be located more than one line forward.
  *
  * <p><b>Example</b>
  *
  * <pre>
  *     if (test1()) {
  *     } else {<caret> if (test2()) {
  *         foo();
  *     }
  * </pre>
  *
  * <p>We want to get this after the processing:
  *
  * <pre>
  *     if (test1()) {
  *     } else {
  *         if (test2()) {
  *             foo();
  *         }
  *     }
  * </pre>
  *
  * I.e. closing brace should be inserted two lines below current caret line. Hence, we need to
  * calculate correct offset to use for brace inserting. This method is responsible for that.
  *
  * <p>In essence it inspects PSI structure and finds PSE elements with the max length that starts
  * at caret offset. End offset of that element is used as an insertion point.
  *
  * @param file target PSI file
  * @param text text from the given file
  * @param offset target offset where line feed will be inserted
  * @return offset to use for inserting closing brace
  */
 protected int calculateOffsetToInsertClosingBrace(
     PsiFile file, CharSequence text, final int offset) {
   PsiElement element = PsiUtilCore.getElementAtOffset(file, offset);
   ASTNode node = element.getNode();
   if (node != null && node.getElementType() == TokenType.WHITE_SPACE) {
     return CharArrayUtil.shiftForwardUntil(text, offset, "\n");
   }
   for (PsiElement parent = element.getParent(); parent != null; parent = parent.getParent()) {
     ASTNode parentNode = parent.getNode();
     if (parentNode == null || parentNode.getStartOffset() != offset) {
       break;
     }
     element = parent;
   }
   if (element.getTextOffset() != offset) {
     return CharArrayUtil.shiftForwardUntil(text, offset, "\n");
   }
   return element.getTextRange().getEndOffset();
 }
Пример #19
0
 private boolean isBlankLine(int line, CharSequence chars) {
   Document document = myDocument;
   if (document == null) {
     return true;
   }
   int startOffset = document.getLineStartOffset(line);
   int endOffset = document.getLineEndOffset(line);
   return CharArrayUtil.shiftForward(chars, startOffset, endOffset, " \t")
       >= myDocument.getLineEndOffset(line);
 }
  @Override
  public int check(@NotNull CharSequence text, int start, int end) {
    for (CharSequence whiteSpace : myWhiteSpaces) {
      if (CharArrayUtil.indexOf(text, whiteSpace, start, end) == start) {
        return start + whiteSpace.length();
      }
    }

    return start;
  }
 @NotNull
 private static String createSequence(@NotNull CharSequence text, int startOffset, int endOffset) {
   if (text instanceof String) {
     return ((String) text).substring(startOffset, endOffset);
   }
   char[] buf = new char[endOffset - startOffset];
   CharArrayUtil.getChars(text, buf, startOffset, 0, buf.length);
   return StringFactory.createShared(
       buf); // this way the .toString() doesn't create another instance (as opposed to new
             // CharArrayCharSequence())
 }
 /**
  * Calculates the position for insertion of one or more '}'.
  *
  * @param file target PSI file
  * @param editor target editor
  * @param caretOffset target caret offset
  * @return the position between <code>caretOffset</code> and the end of file
  */
 protected int getRBraceOffset(
     @NotNull final PsiFile file, @NotNull final Editor editor, int caretOffset) {
   CharSequence text = editor.getDocument().getCharsSequence();
   int offset = CharArrayUtil.shiftForward(text, caretOffset, " \t");
   final int fileLength = text.length();
   if (offset < fileLength && ")];,%<?".indexOf(text.charAt(offset)) < 0) {
     offset = calculateOffsetToInsertClosingBrace(file, text, offset);
     // offset = CharArrayUtil.shiftForwardUntil(text, caretOffset, "\n");
   }
   return Math.min(offset, fileLength);
 }
 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);
 }
  @Override
  public void handleInsert(InsertionContext context) {
    final Document document = context.getEditor().getDocument();
    document.replaceString(context.getStartOffset(), context.getTailOffset(), ";");
    final InsertionContext qualifierContext =
        CompletionUtil.emulateInsertion(context, context.getStartOffset(), myQualifier);
    OffsetKey oldStart = context.trackOffset(context.getStartOffset(), false);

    int start =
        CharArrayUtil.shiftForward(
            context.getDocument().getCharsSequence(), context.getStartOffset(), " \t\n");
    if (shouldParenthesizeQualifier(context.getFile(), start, qualifierContext.getTailOffset())) {
      final String space =
          CodeStyleSettingsManager.getSettings(qualifierContext.getProject())
                  .SPACE_WITHIN_PARENTHESES
              ? " "
              : "";
      document.insertString(start, "(" + space);
      document.insertString(qualifierContext.getTailOffset(), space + ")");
    }

    final char atTail = document.getCharsSequence().charAt(context.getTailOffset() - 1);
    if (atTail != ';') {
      LOG.error(
          LogMessageEx.createEvent(
              "Unexpected character",
              "atTail="
                  + atTail
                  + "\n"
                  + "offset="
                  + context.getTailOffset()
                  + "\n"
                  + "item="
                  + this
                  + "\n"
                  + "item.class="
                  + this.getClass()
                  + "\n"
                  + DebugUtil.currentStackTrace(),
              AttachmentFactory.createAttachment(context.getDocument())));
    }
    document.replaceString(context.getTailOffset() - 1, context.getTailOffset(), ".");

    CompletionUtil.emulateInsertion(getDelegate(), context.getTailOffset(), context);
    context.commitDocument();

    int formatStart = context.getOffset(oldStart);
    int formatEnd = context.getTailOffset();
    if (formatStart >= 0 && formatEnd >= 0) {
      CodeStyleManager.getInstance(context.getProject())
          .reformatText(context.getFile(), formatStart, formatEnd);
    }
  }
 @Override
 public void apply(Editor editor, JavaSmartEnterProcessor processor, PsiElement psiElement)
     throws IncorrectOperationException {
   if (psiElement instanceof PsiEnumConstant) {
     int insertionOffset = psiElement.getTextRange().getEndOffset();
     Document doc = editor.getDocument();
     final CharSequence text = doc.getCharsSequence();
     final int probableCommaOffset = CharArrayUtil.shiftForward(text, insertionOffset, " \t");
     if (probableCommaOffset >= text.length() || text.charAt(probableCommaOffset) != ',') {
       doc.insertString(insertionOffset, ",");
     }
   }
 }
    @Nullable
    private PsiComment createJavaDocStub(
        final CodeInsightSettings settings, final PsiComment comment, final Project project) {
      if (settings.JAVADOC_STUB_ON_ENTER) {
        final DocumentationProvider langDocumentationProvider =
            LanguageDocumentation.INSTANCE.forLanguage(comment.getParent().getLanguage());

        @Nullable final CodeDocumentationProvider docProvider;
        if (langDocumentationProvider instanceof CompositeDocumentationProvider) {
          docProvider =
              ((CompositeDocumentationProvider) langDocumentationProvider)
                  .getFirstCodeDocumentationProvider();
        } else {
          docProvider =
              langDocumentationProvider instanceof CodeDocumentationProvider
                  ? (CodeDocumentationProvider) langDocumentationProvider
                  : null;
        }

        if (docProvider != null) {
          if (docProvider.findExistingDocComment(comment) != comment) return comment;
          String docStub = docProvider.generateDocumentationContentStub(comment);

          if (docStub != null && docStub.length() != 0) {
            myOffset =
                CharArrayUtil.shiftForwardUntil(
                    myDocument.getCharsSequence(), myOffset, LINE_SEPARATOR);
            myOffset =
                CharArrayUtil.shiftForward(myDocument.getCharsSequence(), myOffset, LINE_SEPARATOR);
            myDocument.insertString(myOffset, docStub);
          }
        }

        PsiDocumentManager.getInstance(project).commitAllDocuments();
        return PsiTreeUtil.getNonStrictParentOfType(
            myFile.findElementAt(myOffset), PsiComment.class);
      }
      return comment;
    }
 public void execute(FileViewProvider viewProvider) {
   final Document document = viewProvider.getDocument();
   final PsiFile psiFile = viewProvider.getPsi(viewProvider.getBaseLanguage());
   for (Pair<Integer, RangeMarker> integerRangeMarkerPair : myRangesToReindent) {
     RangeMarker marker = integerRangeMarkerPair.second;
     final CharSequence charsSequence =
         document.getCharsSequence().subSequence(marker.getStartOffset(), marker.getEndOffset());
     final int oldIndent = integerRangeMarkerPair.first;
     final TextRange[] whitespaces =
         CharArrayUtil.getIndents(charsSequence, marker.getStartOffset());
     final int indentAdjustment = getNewIndent(psiFile, marker.getStartOffset()) - oldIndent;
     if (indentAdjustment != 0)
       adjustIndentationInRange(psiFile, document, whitespaces, indentAdjustment);
   }
 }
Пример #28
0
 /**
  * @return position <code>x</code> for which <code>
  *     myDocument.getText().substring(x, startOffset)</code> contains <code>blankLinesNumber
  *     </code> line feeds and <code>myDocument.getText.charAt(x-1) == '\n'</code>
  */
 private int getBlankLineOffset(int blankLinesNumber, int startOffset) {
   int startLine = myDocument.getLineNumber(startOffset);
   if (startLine <= 0) {
     return 0;
   }
   CharSequence text = myDocument.getCharsSequence();
   for (int i = myDocument.getLineStartOffset(startLine - 1) - 1;
       i >= 0;
       i = CharArrayUtil.lastIndexOf(text, "\n", i - 1)) {
     if (--blankLinesNumber <= 0) {
       return i + 1;
     }
   }
   return 0;
 }
  @Override
  public Result preprocessEnter(
      @NotNull final PsiFile file,
      @NotNull final Editor editor,
      @NotNull final Ref<Integer> caretOffsetRef,
      @NotNull final Ref<Integer> caretAdvance,
      @NotNull final DataContext dataContext,
      final EditorActionHandler originalHandler) {
    int caretOffset = caretOffsetRef.get().intValue();
    PsiElement psiAtOffset = file.findElementAt(caretOffset);
    if (psiAtOffset != null && psiAtOffset.getTextOffset() < caretOffset) {
      ASTNode token = psiAtOffset.getNode();
      Document document = editor.getDocument();
      CharSequence text = document.getText();
      final Language language = psiAtOffset.getLanguage();
      final Commenter languageCommenter = LanguageCommenters.INSTANCE.forLanguage(language);
      final CodeDocumentationAwareCommenter commenter =
          languageCommenter instanceof CodeDocumentationAwareCommenter
              ? (CodeDocumentationAwareCommenter) languageCommenter
              : null;
      if (commenter != null && token.getElementType() == commenter.getLineCommentTokenType()) {
        final int offset = CharArrayUtil.shiftForward(text, caretOffset, " \t");

        if (offset < document.getTextLength() && text.charAt(offset) != '\n') {
          String prefix = commenter.getLineCommentPrefix();
          assert prefix != null : "Line Comment type is set but Line Comment Prefix is null!";
          if (!StringUtil.startsWith(text, offset, prefix)) {
            if (text.charAt(caretOffset) != ' ' && !prefix.endsWith(" ")) {
              prefix += " ";
            }
            document.insertString(caretOffset, prefix);
            return Result.Default;
          } else {
            int afterPrefix = offset + prefix.length();
            if (afterPrefix < document.getTextLength() && text.charAt(afterPrefix) != ' ') {
              document.insertString(afterPrefix, " ");
              // caretAdvance.set(0);
            }
            caretOffsetRef.set(offset);
          }
          return Result.Default;
        }
      }
    }
    return Result.Continue;
  }
  private boolean isLineCommented(
      final int line, final CharSequence chars, final Commenter commenter) {
    boolean commented;
    int lineEndForBlockCommenting = -1;
    int lineStart = myDocument.getLineStartOffset(line);
    lineStart = CharArrayUtil.shiftForward(chars, lineStart, " \t");

    if (commenter instanceof SelfManagingCommenter) {
      final SelfManagingCommenter selfManagingCommenter = (SelfManagingCommenter) commenter;
      commented =
          selfManagingCommenter.isLineCommented(
              line, lineStart, myDocument, myCommenterStateMap.get(selfManagingCommenter));
    } else {
      String prefix = commenter.getLineCommentPrefix();

      if (prefix != null) {
        commented =
            CharArrayUtil.regionMatches(chars, lineStart, prefix)
                || prefix.endsWith(" ")
                    && CharArrayUtil.regionMatches(chars, lineStart, prefix.trim() + "\n");
      } else {
        prefix = commenter.getBlockCommentPrefix();
        String suffix = commenter.getBlockCommentSuffix();
        final int textLength = myDocument.getTextLength();
        lineEndForBlockCommenting = myDocument.getLineEndOffset(line);
        if (lineEndForBlockCommenting == textLength) {
          final int shifted = CharArrayUtil.shiftBackward(chars, textLength - 1, " \t");
          if (shifted < textLength - 1) lineEndForBlockCommenting = shifted;
        } else {
          lineEndForBlockCommenting =
              CharArrayUtil.shiftBackward(chars, lineEndForBlockCommenting, " \t");
        }
        commented =
            lineStart == lineEndForBlockCommenting && myStartLine != myEndLine
                || CharArrayUtil.regionMatches(chars, lineStart, prefix)
                    && CharArrayUtil.regionMatches(
                        chars, lineEndForBlockCommenting - suffix.length(), suffix);
      }
    }

    if (commented) {
      myStartOffsets[line - myStartLine] = lineStart;
      myEndOffsets[line - myStartLine] = lineEndForBlockCommenting;
    }

    return commented;
  }