@Override 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, "end")) { caretOffset += 3; } else if (CharArrayUtil.regionMatches(chars, caretOffset, "\nend")) { caretOffset += 4; } // caretOffset = CharArrayUtil.shiftBackward(chars, caretOffset - 3, " \t") + 1; if (CharArrayUtil.regionMatches(chars, caretOffset - "end".length(), "end") || CharArrayUtil.regionMatches(chars, caretOffset - "\nend".length(), "\nend")) { 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 - 4), LuaBlock.class, false); reformat(elt); settings.KEEP_SIMPLE_BLOCKS_IN_ONE_LINE = old; editor.getCaretModel().moveToOffset(caretOffset - 4); } }
@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); } }
@Override public PsiDocTag findTagByName(String name) { if (getFirstChildNode().getElementType() == JavaDocElementType.DOC_COMMENT) { if (getFirstChildNode().getText().indexOf(name) < 0) return null; } for (ASTNode child = getFirstChildNode(); child != null; child = child.getTreeNext()) { if (child.getElementType() == DOC_TAG) { PsiDocTag tag = (PsiDocTag)SourceTreeToPsiMap.treeElementToPsi(child); final CharSequence nameText = ((LeafElement)tag.getNameElement()).getChars(); if (nameText.length() > 0 && nameText.charAt(0) == '@' && CharArrayUtil.regionMatches(nameText, 1, name)) { return tag; } } } return null; }
private static boolean docTagEndsWithLineFeedAndAsterisks(@NotNull ASTNode node) { assert (node.getElementType() == DOC_TAG); ASTNode lastAsterisks = TreeUtil.findChildBackward(node, DOC_COMMENT_LEADING_ASTERISKS); if (lastAsterisks == null || !lastAsterisks.getTreePrev().textContains('\n')) { return false; } //So last asterisk is placed on new line, checking if after it there are no non-whitespace symbols ASTNode last = node.getLastChildNode(); ASTNode current = lastAsterisks; while (current != last) { current = current.getTreeNext(); CharSequence currentText = current.getChars(); if (CharArrayUtil.shiftForward(currentText, 0, " \t") != currentText.length()) return false; } return true; }
@Override protected boolean canUseOffset(@NotNull Document document, int offset, boolean virtual) { if (virtual) { return true; } CharSequence text = document.getCharsSequence(); char c = text.charAt(offset); if (!StringUtil.isWhiteSpace(c)) { return true; } int i = CharArrayUtil.shiftBackward(text, offset, " \t"); if (i < 2) { return true; } return text.charAt(i - 2) != 'd' || text.charAt(i - 1) != 'e' || text.charAt(i) != 'f'; }
@Nullable public static <T extends PsiElement> T getPsiElementAt(final Project project, final Class<T> expectedPsiElementClass, final SourcePosition sourcePosition) { return ApplicationManager.getApplication().runReadAction(new Computable<T>() { public T compute() { final PsiFile psiFile = sourcePosition.getFile(); final Document document = PsiDocumentManager.getInstance(project).getDocument(psiFile); if(document == null) { return null; } final int spOffset = sourcePosition.getOffset(); if (spOffset < 0) { return null; } final int offset = CharArrayUtil.shiftForward(document.getCharsSequence(), spOffset, " \t"); return PsiTreeUtil.getParentOfType(psiFile.findElementAt(offset), expectedPsiElementClass, false); } }); }
@Override public int processTail(final Editor editor, int tailOffset) { int startOffset = tailOffset; CharSequence seq = editor.getDocument().getCharsSequence(); int nextNonWs = CharArrayUtil.shiftForward(seq, tailOffset, " \t"); if (nextNonWs < seq.length() && seq.charAt(nextNonWs) == '{') { tailOffset = nextNonWs + 1; } else { tailOffset = insertChar(editor, startOffset, '{'); } tailOffset = reformatBrace(editor, tailOffset, startOffset); if (EnterAfterUnmatchedBraceHandler.isAfterUnmatchedLBrace(editor, tailOffset, getFileType(editor))) { new EnterHandler(EditorActionManager.getInstance().getActionHandler(IdeActions.ACTION_EDITOR_ENTER)) .executeWriteAction(editor, DataManager.getInstance().getDataContext(editor.getContentComponent())); return editor.getCaretModel().getOffset(); } return tailOffset; }
@NotNull private static Substring expandParamNameSubstring(@NotNull Substring name) { final String superString = name.getSuperString(); int startWithStars = name.getStartOffset(); int prevNonWhitespace = skipSpacesBackward(superString, name.getStartOffset() - 1); if (prevNonWhitespace >= 0 && superString.charAt(prevNonWhitespace) == '*') { startWithStars = CharArrayUtil.shiftBackward(superString, prevNonWhitespace, "*") + 1; prevNonWhitespace = skipSpacesBackward(superString, startWithStars - 1); } if (prevNonWhitespace >= 0 && superString.charAt(prevNonWhitespace) == ',') { return new Substring(superString, prevNonWhitespace, name.getEndOffset()); } // end offset is always exclusive final int nextNonWhitespace = skipSpacesForward(superString, name.getEndOffset()); if (nextNonWhitespace < superString.length() && superString.charAt(nextNonWhitespace) == ',') { // if we remove parameter with trailing comma (i.e. first parameter) remove whitespaces after it as well return new Substring(superString, startWithStars, skipSpacesForward(superString, nextNonWhitespace + 1)); } return name; }
private static void selectWithGuide(Editor editor, IndentGuideDescriptor guide) { final Document doc = editor.getDocument(); int startOffset = editor.logicalPositionToOffset(new LogicalPosition(guide.startLine, 0)); int endOffset = guide.endLine >= doc.getLineCount() ? doc.getTextLength() : doc.getLineStartOffset(guide.endLine); final VirtualFile file = ((EditorEx)editor).getVirtualFile(); if (file != null) { // Make sure selection contains closing matching brace. final CharSequence chars = doc.getCharsSequence(); int nonWhitespaceOffset = CharArrayUtil.shiftForward(chars, endOffset, " \t\n"); HighlighterIterator iterator = ((EditorEx)editor).getHighlighter().createIterator(nonWhitespaceOffset); if (BraceMatchingUtil.isRBraceToken(iterator, chars, file.getFileType())) { if (((EditorEx)editor).calcColumnNumber(iterator.getStart(), doc.getLineNumber(iterator.getStart())) == guide.indentLevel) { endOffset = iterator.getEnd(); endOffset = CharArrayUtil.shiftForward(chars, endOffset, " \t"); if (endOffset < chars.length() && chars.charAt(endOffset) == '\n') endOffset++; } } } editor.getSelectionModel().setSelection(startOffset, endOffset); }
public static Result navigateToLineEnd(@NotNull Editor editor, @NotNull PsiFile psiFile) { final Document document = editor.getDocument(); final CaretModel caretModel = editor.getCaretModel(); final int offset = caretModel.getOffset(); final CharSequence text = document.getCharsSequence(); int line = caretModel.getLogicalPosition().line; final int endLineOffset = document.getLineEndOffset(line); final LogicalPosition endLineLogicalPosition = editor.offsetToLogicalPosition(endLineOffset); // Stop processing if there are non-white space symbols after the current caret position. final int lastNonWsSymbolOffset = CharArrayUtil.shiftBackward(text, endLineOffset, " \t"); if (lastNonWsSymbolOffset > offset || caretModel.getLogicalPosition().column > endLineLogicalPosition.column) { return Result.CONTINUE; } final Pair<JavadocHelper.JavadocParameterInfo,List<JavadocHelper.JavadocParameterInfo>> pair = ourHelper.parse(psiFile, editor, offset); if (pair.first == null || pair.first.parameterDescriptionStartPosition != null) { return Result.CONTINUE; } final LogicalPosition position = ourHelper.calculateDescriptionStartPosition(psiFile, pair.second, pair.first); ourHelper.navigate(position, editor, psiFile.getProject()); return Result.STOP; }
private static boolean mustHaveNewLineBefore(String line) { final int nonWs = CharArrayUtil.shiftForward(line, 0, " \t"); if (nonWs < line.length()) { line = line.substring(nonWs); } if (line.startsWith("at")) return true; // Start of the new stack frame entry if (line.startsWith("Caused")) return true; // Caused by message if (line.startsWith("- locked")) return true; // "Locked a monitor" logging if (line.startsWith("- waiting")) return true; // "Waiting for monitor" logging if (line.startsWith("- parking to wait")) return true; if (line.startsWith("java.lang.Thread.State")) return true; if (line.startsWith("\"")) return true; // Start of the new thread (thread name) return false; }
public static Indent getMinLineIndent(Project project, Document document, int line1, int line2, FileType fileType) { CharSequence chars = document.getCharsSequence(); CodeStyleManager codeStyleManager = CodeStyleManager.getInstance(project); Indent minIndent = null; for (int line = line1; line <= line2; line++) { int lineStart = document.getLineStartOffset(line); int textStart = CharArrayUtil.shiftForward(chars, lineStart, " \t"); if (textStart >= document.getTextLength()) { textStart = document.getTextLength(); } else { char c = chars.charAt(textStart); if (c == '\n' || c == '\r') continue; // empty line } String space = chars.subSequence(lineStart, textStart).toString(); Indent indent = codeStyleManager.getIndent(space, fileType); minIndent = minIndent != null ? indent.min(minIndent) : indent; } if (minIndent == null && line1 == line2 && line1 < document.getLineCount() - 1) { return getMinLineIndent(project, document, line1 + 1, line1 + 1, fileType); } //if (minIndent == Integer.MAX_VALUE){ // minIndent = 0; //} return minIndent; }
@Override public void executeWriteAction(@NotNull Editor editor, Caret caret, DataContext dataContext) { final Document document = editor.getDocument(); final int caretOffset = editor.getCaretModel().getOffset(); if (caretOffset < 1) { return; } final SelectionModel selectionModel = editor.getSelectionModel(); final CharSequence text = document.getCharsSequence(); final char c = text.charAt(caretOffset - 1); if (!selectionModel.hasSelection() && StringUtil.isWhiteSpace(c)) { int startOffset = CharArrayUtil.shiftBackward(text, caretOffset - 2, "\t \n") + 1; document.deleteString(startOffset, caretOffset); } else { final EditorActionHandler handler = EditorActionManager.getInstance().getActionHandler(IdeActions.ACTION_EDITOR_BACKSPACE); handler.execute(editor, caret, dataContext); } }
private static boolean isSimilarFile(FileContent inputData) { if (CharArrayUtil.indexOf(inputData.getContentAsText(), "<" + RESOURCES_ROOT_TAG, 0) < 0) { return false; } final boolean[] ourRootTag = {false}; NanoXmlUtil.parse(CharArrayUtil.readerFromCharSequence(inputData.getContentAsText()), new NanoXmlUtil.IXMLBuilderAdapter() { @Override public void startElement(String name, String nsPrefix, String nsURI, String systemID, int lineNr) throws Exception { ourRootTag[0] = RESOURCES_ROOT_TAG.equals(name) && nsPrefix == null; stop(); } }); return ourRootTag[0]; }
/** * Utility method that does the following: * <pre> * <ol> * <li>Checks if target document line that contains given offset starts with '*';</li> * <li>Returns document text located between the '*' and first non-white space symbols after it if the check above is successful;</li> * </ol> </pre> * * @param document target document * @param offset target offset that identifies line to check and max offset to use during scanning * @return */ @Nullable public static String getIndentInsideJavadoc(@NotNull Document document, int offset) { CharSequence text = document.getCharsSequence(); if (offset >= text.length()) { return null; } int line = document.getLineNumber(offset); int lineStartOffset = document.getLineStartOffset(line); int lineEndOffset = document.getLineEndOffset(line); int i = CharArrayUtil.shiftForward(text, lineStartOffset, " \t"); if (i > lineEndOffset || text.charAt(i) != '*') { return null; } int start = i + 1; int end = CharArrayUtil.shiftForward(text, start, " \t"); end = Math.min(end, lineEndOffset); return end > start ? text.subSequence(start, end).toString() : ""; }
@SuppressWarnings({"HardCodedStringLiteral"}) private static void compoundLineLink(StringBuffer lineAnchor, PsiElement psiElement) { final PsiFile file = psiElement.getContainingFile(); if (file != null) { final VirtualFile vFile = file.getVirtualFile(); if (vFile != null) { Document doc = FileDocumentManager.getInstance().getDocument(vFile); final int lineNumber = doc.getLineNumber(psiElement.getTextOffset()) + 1; lineAnchor.append(" ").append(InspectionsBundle.message("inspection.export.results.at.line")).append(" "); lineAnchor.append("<a HREF=\""); try { int offset = doc.getLineStartOffset(lineNumber - 1); offset = CharArrayUtil.shiftForward(doc.getCharsSequence(), offset, " \t"); lineAnchor.append(new URL(vFile.getUrl() + "#" + offset)); } catch (MalformedURLException e) { LOG.error(e); } lineAnchor.append("\">"); lineAnchor.append(Integer.toString(lineNumber)); lineAnchor.append("</a>"); } } }
private static int getLineStartOffset(final int offset, final WhiteSpace whiteSpace, final FormattingDocumentModel documentModel) { int lineStartOffset = offset; CharSequence text = getCharSequence(documentModel); lineStartOffset = CharArrayUtil.shiftBackwardUntil(text, lineStartOffset, " \t\n"); if (lineStartOffset > whiteSpace.getStartOffset()) { if (lineStartOffset >= text.length()) lineStartOffset = text.length() - 1; final int wsStart = whiteSpace.getStartOffset(); int prevEnd; if (text.charAt(lineStartOffset) == '\n' && wsStart <= (prevEnd = documentModel.getLineStartOffset(documentModel.getLineNumber(lineStartOffset - 1))) && documentModel.getText(new TextRange(prevEnd, lineStartOffset)).toString().trim().length() == 0 // ws consists of space only, it is not true for <![CDATA[ ) { lineStartOffset--; } lineStartOffset = CharArrayUtil.shiftBackward(text, lineStartOffset, "\t "); if (lineStartOffset < 0) lineStartOffset = 0; if (lineStartOffset != offset && text.charAt(lineStartOffset) == '\n') { lineStartOffset++; } } return lineStartOffset; }
private static TextRange getSignificantRange(final PsiFile file, final int offset) { final ASTNode elementAtOffset = SourceTreeToPsiMap.psiElementToTree(CodeStyleManagerImpl.findElementInTreeWithFormatterEnabled(file, offset)); if (elementAtOffset == null) { int significantRangeStart = CharArrayUtil.shiftBackward(file.getText(), offset - 1, "\r\t "); return new TextRange(Math.max(significantRangeStart, 0), offset); } final FormattingModelBuilder builder = LanguageFormatting.INSTANCE.forContext(file); final TextRange textRange = builder.getRangeAffectingIndent(file, offset, elementAtOffset); if (textRange != null) { return textRange; } return elementAtOffset.getTextRange(); }
private static boolean isTheOne(@NotNull ArchiveHandler.EntryInfo entry, @NotNull CharSequence relativePath) { int endIndex = relativePath.length(); for (ArchiveHandler.EntryInfo e = entry; e != null; e = e.parent) { CharSequence shortName = e.shortName; if (!CharArrayUtil.regionMatches(relativePath, endIndex - shortName.length(), relativePath.length(), shortName)) { return false; } endIndex -= shortName.length(); if (e.parent != null && e.parent.shortName.length() != 0 && endIndex != 0) { // match "/" if (relativePath.charAt(endIndex-1) == '/') { endIndex -= 1; } else { return false; } } } return endIndex==0; }
public static boolean isIgnoredNode(PsiElement element) { // ex. "var i = 0" in AS: empty JSAttributeList should be skipped /*if (element.getText().length() == 0) { return true; }*/ if (element instanceof PsiWhiteSpace || element instanceof PsiErrorElement || element instanceof PsiComment) { return true; } if (!(element instanceof LeafElement)) { return false; } if (CharArrayUtil.containsOnlyWhiteSpaces(element.getText())) { return true; } EquivalenceDescriptorProvider descriptorProvider = EquivalenceDescriptorProvider.getInstance(element); if (descriptorProvider == null) { return false; } final IElementType elementType = ((LeafElement)element).getElementType(); return descriptorProvider.getIgnoredTokens().contains(elementType); }
private int getPrevOrNextParameterOffset(boolean isNext) { if (!(myHandler instanceof ParameterInfoHandlerWithTabActionSupport)) return -1; int offset = CharArrayUtil.shiftBackward(myEditor.getDocument().getCharsSequence(), myEditor.getCaretModel().getOffset() - 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; ParameterInfoHandlerWithTabActionSupport handler = (ParameterInfoHandlerWithTabActionSupport)myHandler; int currentParameterIndex = ParameterInfoUtils.getCurrentParameterIndex(argList.getNode(), offset, handler.getActualParameterDelimiterType()); if (currentParameterIndex == -1) return -1; @SuppressWarnings("unchecked") PsiElement[] parameters = handler.getActualParameters(argList); int prevOrNextParameterIndex = isNext && currentParameterIndex < parameters.length - 1 ? currentParameterIndex + 1 : !isNext && currentParameterIndex > 0 ? currentParameterIndex - 1 : -1; return prevOrNextParameterIndex != -1 ? parameters[prevOrNextParameterIndex].getTextRange().getStartOffset() : -1; }
public void iterate(MarkupIterator iterator, int endOffset) { while (!iterator.atEnd()) { iterator.advance(); int startOffset = iterator.getStartOffset(); if (startOffset >= endOffset) { break; } if (myStartOffset < 0) { myStartOffset = startOffset; } boolean whiteSpacesOnly = CharArrayUtil.isEmptyOrSpaces(myText, startOffset, iterator.getEndOffset()); processBackground(startOffset, iterator.getBackgroundColor()); if (!whiteSpacesOnly) { processForeground(startOffset, iterator.getForegroundColor()); processFontFamilyName(startOffset, iterator.getFontFamilyName()); processFontStyle(startOffset, iterator.getFontStyle()); } } addTextIfPossible(endOffset); }
@Nullable private static Commenter findCommenter(Editor editor, PsiFile file, final int line) { final FileType fileType = file.getFileType(); if (fileType instanceof AbstractFileType) { return ((AbstractFileType)fileType).getCommenter(); } Document document = editor.getDocument(); int lineStartOffset = document.getLineStartOffset(line); int lineEndOffset = document.getLineEndOffset(line) - 1; final CharSequence charSequence = document.getCharsSequence(); lineStartOffset = CharArrayUtil.shiftForward(charSequence, lineStartOffset, " \t"); lineEndOffset = CharArrayUtil.shiftBackward(charSequence, lineEndOffset < 0 ? 0 : lineEndOffset, " \t"); final Language lineStartLanguage = PsiUtilCore.getLanguageAtOffset(file, lineStartOffset); final Language lineEndLanguage = PsiUtilCore.getLanguageAtOffset(file, lineEndOffset); return CommentByBlockCommentHandler.getCommenter(file, editor, lineStartLanguage, lineEndLanguage); }
private static void uncommentRange(Document document, int startOffset, int endOffset, @NotNull Commenter commenter) { final String commentedSuffix = commenter.getCommentedBlockCommentSuffix(); final String commentedPrefix = commenter.getCommentedBlockCommentPrefix(); final String prefix = commenter.getBlockCommentPrefix(); final String suffix = commenter.getBlockCommentSuffix(); if (prefix == null || suffix == null) { return; } if (endOffset >= suffix.length() && CharArrayUtil.regionMatches(document.getCharsSequence(), endOffset - suffix.length(), suffix)) { document.deleteString(endOffset - suffix.length(), endOffset); endOffset -= suffix.length(); } if (commentedPrefix != null && commentedSuffix != null) { CommentByBlockCommentHandler.commentNestedComments(document, new TextRange(startOffset, endOffset), commenter); } document.deleteString(startOffset, startOffset + prefix.length()); }
@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 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); }
private Couple<TextRange> findCommentBlock(TextRange range, String commentPrefix, String commentSuffix) { CharSequence chars = myDocument.getCharsSequence(); int startOffset = range.getStartOffset(); boolean endsProperly = CharArrayUtil.regionMatches(chars, range.getEndOffset() - commentSuffix.length(), commentSuffix); TextRange start = expandRange(startOffset, startOffset + commentPrefix.length()); TextRange end; if (endsProperly) { end = expandRange(range.getEndOffset() - commentSuffix.length(), range.getEndOffset()); } else { end = new TextRange(range.getEndOffset(), range.getEndOffset()); } return Couple.of(start, end); }
@NotNull public LuaDocTag[] findTagsByName(@NonNls String name) { if (!getText().contains(name)) return LuaDocTag.EMPTY_ARRAY; ArrayList<LuaDocTag> list = new ArrayList<LuaDocTag>(); for (PsiElement e = getFirstChild(); e != null; e = e.getNextSibling()) { if (e instanceof LuaDocTag && CharArrayUtil.regionMatches(((LuaDocTag)e).getName(), 1, name)) { list.add((LuaDocTag)e); } } return list.toArray(new LuaDocTag[list.size()]); }
private void handleEndingQuote(final InsertionContext insertionContext) { final int caretOffset = insertionContext.getEditor().getCaretModel().getOffset(); final CharSequence chars = insertionContext.getDocument().getCharsSequence(); final boolean hasEndingQuote = CharArrayUtil.regionMatches(chars, caretOffset, "\""); if (!hasEndingQuote) { insertionContext.getDocument().insertString(caretOffset, "\""); EditorModificationUtil.moveCaretRelatively(insertionContext.getEditor(), 1); } }
public static boolean hasErrorElementsNearby(final PsiFile file, int startOffset, int endOffset) { endOffset = CharArrayUtil.shiftForward(file.getViewProvider().getContents(), endOffset, " \t\n"); for (PsiElement element : CollectHighlightsUtil.getElementsInRange(file, startOffset, endOffset)) { if (element instanceof PsiErrorElement) { return true; } } return false; }
@Override public final void start(@NotNull CharSequence buffer, int startOffset, int endOffset, int initialState) { myBuffer = buffer; myBufferArray = CharArrayUtil.fromSequenceWithoutCopying(buffer); myBufferIndex = startOffset; myBufferEndOffset = endOffset; myTokenType = null; myTokenEndOffset = startOffset; myFlexLexer.reset(myBuffer, startOffset, endOffset, 0); }
protected final void locateToken() { if (myTokenType != null) return; _locateToken(); if (myTokenType == myTokenTypes.space()) { myAfterLineBreak = CharArrayUtil.containLineBreaks(myBuffer, getTokenStart(), getTokenEnd()); } }
private static boolean nodeIsNextAfterAsterisks(@NotNull ASTNode node) { ASTNode current = TreeUtil.findSiblingBackward(node, DOC_COMMENT_LEADING_ASTERISKS); if (current == null || current == node) return false; while (current.getTreeNext() != node) { current = current.getTreeNext(); CharSequence currentText = current.getChars(); if (CharArrayUtil.shiftForward(currentText, 0, " \t") != currentText.length()) return false; } return true; }
private static boolean shouldSkipLine(final PsiFile file, Document doc, int line) { final int start = doc.getLineStartOffset(line); final int end = doc.getLineEndOffset(line); final int _start = CharArrayUtil.shiftForward(doc.getCharsSequence(), start, " \n\t"); if (_start >= end) { return true; } TextRange alreadyChecked = null; for (PsiElement elem = file.findElementAt(_start); elem != null && elem.getTextOffset() <= end && (alreadyChecked == null || !alreadyChecked .contains(elem.getTextRange())); elem = elem.getNextSibling()) { for (PsiElement _elem = elem; _elem.getTextOffset() >= _start; _elem = _elem.getParent()) { alreadyChecked = _elem.getTextRange(); if (_elem instanceof PsiDeclarationStatement) { final PsiElement[] declared = ((PsiDeclarationStatement)_elem).getDeclaredElements(); for (PsiElement declaredElement : declared) { if (declaredElement instanceof PsiVariable) { return false; } } } if (_elem instanceof PsiJavaCodeReferenceElement) { final PsiElement resolved = ((PsiJavaCodeReferenceElement)_elem).resolve(); if (resolved instanceof PsiVariable) { return false; } } } } return true; }
@Nullable public PsiMethod getPsiMethod() { Document document = getDocument(); if(document == null) { return null; } PsiFile psiFile = PsiDocumentManager.getInstance(myProject).getPsiFile(document); if(psiFile instanceof PsiJavaFile) { int line = getLineIndex(); final int offset = CharArrayUtil.shiftForward(document.getCharsSequence(), document.getLineStartOffset(line), " \t"); return DebuggerUtilsEx.findPsiMethod(psiFile, offset); } return null; }
@Override public void updateParameterInfo(@NotNull final PsiAnnotationParameterList parameterOwner, @NotNull final UpdateParameterInfoContext context) { CharSequence chars = context.getEditor().getDocument().getCharsSequence(); int offset1 = CharArrayUtil.shiftForward(chars, context.getEditor().getCaretModel().getOffset(), " \t"); final char c = chars.charAt(offset1); if (c == ',' || c == ')') { offset1 = CharArrayUtil.shiftBackward(chars, offset1 - 1, " \t"); } context.setHighlightedParameter(findAnnotationMethod(context.getFile(), offset1)); }
@Override public void handleInsert(InsertionContext context) { final Document document = context.getEditor().getDocument(); document.replaceString(context.getStartOffset(), context.getTailOffset(), ";"); myQualifier.putUserData(CHAIN_QUALIFIER, true); final InsertionContext qualifierContext = CompletionUtil.emulateInsertion(context, context.getStartOffset(), myQualifier); OffsetKey oldStart = context.trackOffset(context.getStartOffset(), false); PsiDocumentManager.getInstance(context.getProject()).doPostponedOperationsAndUnblockDocument(document); 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 != ';') { return; } 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 boolean doEnter(Editor editor, PsiElement psiElement, boolean isModified) { PsiElement parent = psiElement.getParent(); if (!(parent instanceof PsiCodeBlock)) { return false; } final ASTNode node = psiElement.getNode(); if (node != null && CONTROL_FLOW_ELEMENT_TYPES.contains(node.getElementType())) { return false; } boolean leaveCodeBlock = isControlFlowBreak(psiElement); if (!leaveCodeBlock) { return false; } final int offset = parent.getTextRange().getEndOffset(); // Check if there is empty line after the code block. Just move caret there in the case of the positive answer. final CharSequence text = editor.getDocument().getCharsSequence(); if (offset < text.length() - 1) { final int i = CharArrayUtil.shiftForward(text, offset + 1, " \t"); if (i < text.length() && text.charAt(i) == '\n') { editor.getCaretModel().moveToOffset(offset + 1); EditorActionManager actionManager = EditorActionManager.getInstance(); EditorActionHandler actionHandler = actionManager.getActionHandler(IdeActions.ACTION_EDITOR_MOVE_LINE_END); final DataContext dataContext = DataManager.getInstance().getDataContext(editor.getComponent()); if (dataContext != null) { actionHandler.execute(editor, dataContext); return true; } } } editor.getCaretModel().moveToOffset(offset); return false; }
@Override public void apply(Editor editor, JavaSmartEnterProcessor processor, PsiElement psiElement) throws IncorrectOperationException { if (psiElement instanceof XmlTag) { final ASTNode emptyTagEnd = XmlChildRole.EMPTY_TAG_END_FINDER.findChild(psiElement.getNode()); final ASTNode endTagEnd = XmlChildRole.START_TAG_END_FINDER.findChild(psiElement.getNode()); if (emptyTagEnd != null || endTagEnd != null) return; int insertionOffset = psiElement.getTextRange().getEndOffset(); Document doc = editor.getDocument(); final int caretAt = editor.getCaretModel().getOffset(); final CharSequence text = doc.getCharsSequence(); final int probableCommaOffset = CharArrayUtil.shiftForward(text, insertionOffset, " \t"); //if (caretAt < probableCommaOffset) { // final CharSequence tagName = text.subSequence(psiElement.getTextRange().getStartOffset() + 1, caretAt); // doc.insertString(caretAt, ">"); // doc.insertString(probableCommaOffset + 1, "</" + tagName + ">"); // return; //} char ch; if (probableCommaOffset >= text.length() || ( (ch = text.charAt(probableCommaOffset)) != '/' && ch != '>' ) ) { doc.insertString(insertionOffset, "/>"); } } }
@Nullable private static LineRange createRange(@NotNull Document document, @NotNull PsiElement startElement, @NotNull PsiElement endElement) { CharSequence text = document.getImmutableCharSequence(); int startOffset = startElement.getTextRange().getStartOffset(); int startLine = document.getLineNumber(startOffset); if (!CharArrayUtil.isEmptyOrSpaces(text, document.getLineStartOffset(startLine), startOffset)) { return null; } int endOffset = endElement.getTextRange().getEndOffset(); int endLine = document.getLineNumber(endOffset); if (!CharArrayUtil.isEmptyOrSpaces(text, endOffset, document.getLineEndOffset(endLine))) { return null; } return new LineRange(startLine, endLine + 1); }