public boolean isLineCommented(final int startOfLineOffset, final int endOfLineOffset) { Commenter commenter = getCommenterRange(startOfLineOffset, endOfLineOffset); if (commenter != null) { String lineCommentPrefix = commenter.getLineCommentPrefix(); String blockCommentPrefix = commenter.getCommentedBlockCommentPrefix(); if (blockCommentPrefix == null) blockCommentPrefix = commenter.getBlockCommentPrefix(); String blockCommentSuffix = commenter.getCommentedBlockCommentSuffix(); if (blockCommentSuffix == null) blockCommentSuffix = commenter.getBlockCommentSuffix(); BasedSequence chars = myChars.subSequence(startOfLineOffset, endOfLineOffset); BasedSequence trimmed = chars.trim(); return lineCommentPrefix != null && trimmed.startsWith(lineCommentPrefix) || blockCommentPrefix != null && blockCommentSuffix != null && trimmed.startsWith(blockCommentPrefix) && trimmed.endsWith(blockCommentSuffix); } else { return false; } }
@NotNull @Override public PsiElement[] getElementsToSurround(PsiFile file, int startOffset, int endOffset) { if (startOffset >= endOffset) return PsiElement.EMPTY_ARRAY; Commenter commenter = LanguageCommenters.INSTANCE.forLanguage(file.getLanguage()); if (commenter == null || commenter.getLineCommentPrefix() == null) return PsiElement.EMPTY_ARRAY; PsiElement startElement = file.findElementAt(startOffset); if (startElement instanceof PsiWhiteSpace) startElement = startElement.getNextSibling(); PsiElement endElement = file.findElementAt(endOffset - 1); if (endElement instanceof PsiWhiteSpace) endElement = endElement.getPrevSibling(); if (startElement != null && endElement != null) { startElement = findClosestParentAfterLineBreak(startElement); if (startElement != null) { endElement = findClosestParentBeforeLineBreak(endElement); if (endElement != null) { return adjustRange(startElement, endElement); } } } return PsiElement.EMPTY_ARRAY; }
@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()); }
private static void commentLine(Block block, int line, int offset) { Commenter commenter = block.blockSuitableCommenter; Document document = block.editor.getDocument(); if (commenter == null) commenter = findCommenter(block.editor, block.psiFile, line); if (commenter == null) return; if (commenter instanceof SelfManagingCommenter) { final SelfManagingCommenter selfManagingCommenter = (SelfManagingCommenter)commenter; selfManagingCommenter.commentLine(line, offset, document, block.commenterStateMap.get(selfManagingCommenter)); return; } int endOffset = document.getLineEndOffset(line); RangeMarker marker = document.createRangeMarker(offset, endOffset); marker.setGreedyToLeft(true); marker.setGreedyToRight(true); try { if (doCommentLine(block, line, offset, endOffset, commenter, document)) return; CommentByBlockCommentHandler.processDocument(document, marker, commenter, true); } finally { marker.dispose(); } }
@Nullable public static Commenter getCommenter(final PsiFile file, final Editor editor, final Language lineStartLanguage, final Language lineEndLanguage) { final FileViewProvider viewProvider = file.getViewProvider(); for (MultipleLangCommentProvider provider : MultipleLangCommentProvider.EP_NAME.getExtensions()) { if (provider.canProcess(file, viewProvider)) { return provider.getLineCommenter(file, editor, lineStartLanguage, lineEndLanguage); } } final Language fileLanguage = file.getLanguage(); Language lang = lineStartLanguage == null || LanguageCommenters.INSTANCE.forLanguage(lineStartLanguage) == null || fileLanguage.getBaseLanguage() == lineStartLanguage // file language is a more specific dialect of the line language ? fileLanguage : lineStartLanguage; if (viewProvider instanceof TemplateLanguageFileViewProvider && lang == ((TemplateLanguageFileViewProvider)viewProvider).getTemplateDataLanguage()) { lang = viewProvider.getBaseLanguage(); } return LanguageCommenters.INSTANCE.forLanguage(lang); }
/** * Analyzes position at the given offset at the given text and returns information about comments presence and kind there if any. * * @param file target file being edited (necessary for language recognition at target offset. Language is necessary * to get information about specific comment syntax) * @param chars target text * @param offset target offset at the given text * @param lineStartOffset start offset of the line that contains given offset * @return object that encapsulates information about comments at the given offset at the given text */ @NotNull public static CommentContext tryParseCommentContext(@NotNull PsiFile file, @NotNull CharSequence chars, int offset, int lineStartOffset) { Commenter langCommenter = LanguageCommenters.INSTANCE.forLanguage(PsiUtilCore.getLanguageAtOffset(file, offset)); final boolean isInsideCommentLikeCode = langCommenter instanceof CodeDocumentationAwareCommenter; if (!isInsideCommentLikeCode) { return new CommentContext(); } final CodeDocumentationAwareCommenter commenter = (CodeDocumentationAwareCommenter)langCommenter; int commentStartOffset = CharArrayUtil.shiftForward(chars, lineStartOffset, " \t"); boolean docStart = commenter.getDocumentationCommentPrefix() != null && CharArrayUtil.regionMatches(chars, commentStartOffset, commenter.getDocumentationCommentPrefix()); boolean cStyleStart = commenter.getBlockCommentPrefix() != null && CharArrayUtil.regionMatches(chars, commentStartOffset, commenter.getBlockCommentPrefix()); boolean docAsterisk = commenter.getDocumentationCommentLinePrefix() != null && CharArrayUtil.regionMatches(chars, commentStartOffset, commenter.getDocumentationCommentLinePrefix()); final int firstNonSpaceInLine = CharArrayUtil.shiftForward(chars, offset, " \t"); boolean slashSlash = commenter.getLineCommentPrefix() != null && CharArrayUtil.regionMatches(chars, commentStartOffset, commenter.getLineCommentPrefix()) && firstNonSpaceInLine < chars.length() && chars.charAt(firstNonSpaceInLine) != '\n'; return new CommentContext(commenter, docStart, cStyleStart, docAsterisk, slashSlash, commentStartOffset); }
private static void tryConvertEndOfLineComment(Document doc, PsiElement commentElement) { Commenter commenter = LanguageCommenters.INSTANCE.forLanguage(commentElement.getLanguage()); if (commenter instanceof CodeDocumentationAwareCommenter) { CodeDocumentationAwareCommenter docCommenter = (CodeDocumentationAwareCommenter) commenter; String lineCommentPrefix = commenter.getLineCommentPrefix(); String blockCommentPrefix = commenter.getBlockCommentPrefix(); String blockCommentSuffix = commenter.getBlockCommentSuffix(); if (commentElement.getNode().getElementType() == docCommenter.getLineCommentTokenType() && blockCommentPrefix != null && blockCommentSuffix != null && lineCommentPrefix != null) { String commentText = StringUtil.trimStart(commentElement.getText(), lineCommentPrefix); try { Project project = commentElement.getProject(); PsiParserFacade parserFacade = PsiParserFacade.SERVICE.getInstance(project); PsiComment newComment = parserFacade.createBlockCommentFromText(commentElement.getLanguage(), commentText); commentElement.replace(newComment); PsiDocumentManager.getInstance(project).doPostponedOperationsAndUnblockDocument(doc); } catch (IncorrectOperationException e) { LOG.info("Failed to replace line comment with block comment", e); } } } }
@Nullable private static String getUncommentedText(@NotNull final PsiComment comment) { final PsiFile psiFile = comment.getContainingFile(); final Language language = psiFile.getViewProvider().getBaseLanguage(); final Commenter commenter = LanguageCommenters.INSTANCE.forLanguage(language); if (commenter != null) { String text = comment.getText(); final String prefix = commenter.getBlockCommentPrefix(); if (prefix != null && text.startsWith(prefix)) { text = text.substring(prefix.length()); final String suffix = commenter.getBlockCommentSuffix(); if (suffix != null && text.length() > suffix.length()) { return text.substring(0, text.length() - suffix.length()).trim(); } } } return null; }
@NotNull @Override public PsiElement[] getElementsToSurround(PsiFile file, int startOffset, int endOffset) { if (startOffset >= endOffset - 1) return PsiElement.EMPTY_ARRAY; Commenter commenter = LanguageCommenters.INSTANCE.forLanguage(file.getLanguage()); if (commenter == null || commenter.getLineCommentPrefix() == null) return PsiElement.EMPTY_ARRAY; PsiElement startElement = file.findElementAt(startOffset); if (startElement instanceof PsiWhiteSpace) startElement = startElement.getNextSibling(); PsiElement endElement = file.findElementAt(endOffset - 1); if (endElement instanceof PsiWhiteSpace) endElement = endElement.getPrevSibling(); if (startElement != null && endElement != null) { if (startElement.getTextRange().getStartOffset() > endElement.getTextRange().getStartOffset()) return PsiElement.EMPTY_ARRAY; startElement = findClosestParentAfterLineBreak(startElement); if (startElement != null) { endElement = findClosestParentBeforeLineBreak(endElement); if (endElement != null) { PsiElement commonParent = startElement.getParent(); if (endElement.getParent() == commonParent) { if (startElement == endElement) return new PsiElement[] {startElement}; return new PsiElement[] {startElement, endElement}; } } } } return PsiElement.EMPTY_ARRAY; }
@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); }
private void uncommentRange(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(myDocument.getCharsSequence(), endOffset - suffix.length(), suffix)) { myDocument.deleteString(endOffset - suffix.length(), endOffset); } if (commentedPrefix != null && commentedSuffix != null) { CommentByBlockCommentHandler.commentNestedComments(myDocument, new TextRange(startOffset, endOffset), commenter); } myDocument.deleteString(startOffset, startOffset + prefix.length()); }
/** * Analyzes position at the given offset at the given text and returns information about comments presence and kind there if any. * * @param file target file being edited (necessary for language recognition at target offset. Language is necessary * to get information about specific comment syntax) * @param chars target text * @param offset target offset at the given text * @param lineStartOffset start offset of the line that contains given offset * @return object that encapsulates information about comments at the given offset at the given text */ @NotNull public static CommentContext tryParseCommentContext(@NotNull PsiFile file, @NotNull CharSequence chars, int offset, int lineStartOffset) { Commenter langCommenter = LanguageCommenters.INSTANCE.forLanguage(PsiUtilBase.getLanguageAtOffset(file, offset)); final boolean isInsideCommentLikeCode = langCommenter instanceof CodeDocumentationAwareCommenter; if (!isInsideCommentLikeCode) { return new CommentContext(); } final CodeDocumentationAwareCommenter commenter = (CodeDocumentationAwareCommenter)langCommenter; int commentStartOffset = CharArrayUtil.shiftForward(chars, lineStartOffset, " \t"); boolean docStart = commenter.getDocumentationCommentPrefix() != null && CharArrayUtil.regionMatches(chars, commentStartOffset, commenter.getDocumentationCommentPrefix()); boolean cStyleStart = commenter.getBlockCommentPrefix() != null && CharArrayUtil.regionMatches(chars, commentStartOffset, commenter.getBlockCommentPrefix()); boolean docAsterisk = commenter.getDocumentationCommentLinePrefix() != null && CharArrayUtil.regionMatches(chars, commentStartOffset, commenter.getDocumentationCommentLinePrefix()); final int firstNonSpaceInLine = CharArrayUtil.shiftForward(chars, offset, " \t"); boolean slashSlash = commenter.getLineCommentPrefix() != null && CharArrayUtil.regionMatches(chars, commentStartOffset, commenter.getLineCommentPrefix()) && firstNonSpaceInLine < chars.length() && chars.charAt(firstNonSpaceInLine) != '\n'; return new CommentContext(commenter, docStart, cStyleStart, docAsterisk, slashSlash, commentStartOffset); }
private boolean isCommentToken(PsiElement e, CharSequence token) { final Commenter commenter = LanguageCommenters.INSTANCE.forLanguage(HaxeLanguage.INSTANCE); assert(commenter instanceof HaxeCommenter); final IElementType tokenType = e.getNode().getElementType(); if (tokenType == HaxeTokenTypeSets.DOC_COMMENT) { // XXX: Should we be checking that the token is at the beginning or end of the element? // Or, that the line prefix is actually the first thing on the line? return ((HaxeCommenter)commenter).getDocumentationCommentLinePrefix().contentEquals(token) || ((HaxeCommenter)commenter).getDocumentationCommentPrefix().contentEquals(token) || ((HaxeCommenter)commenter).getDocumentationCommentSuffix().contentEquals(token) // A lot of folks don't use the proper doc comment terminator "**/", and the compiler // accepts a normal block comment terminator "*/". || commenter.getBlockCommentSuffix().contentEquals(token); } else if (tokenType == HaxeTokenTypeSets.MML_COMMENT) { return commenter.getBlockCommentPrefix().contentEquals(token) || commenter.getBlockCommentSuffix().contentEquals(token); } return commenter.getLineCommentPrefix().contentEquals(token); }
@Nonnull @Override public PsiElement[] getElementsToSurround(PsiFile file, int startOffset, int endOffset) { if (startOffset >= endOffset - 1) return PsiElement.EMPTY_ARRAY; Commenter commenter = LanguageCommenters.INSTANCE.forLanguage(file.getLanguage()); if (commenter == null || commenter.getLineCommentPrefix() == null) return PsiElement.EMPTY_ARRAY; PsiElement startElement = file.findElementAt(startOffset); if (startElement instanceof PsiWhiteSpace) startElement = startElement.getNextSibling(); PsiElement endElement = file.findElementAt(endOffset - 1); if (endElement instanceof PsiWhiteSpace) endElement = endElement.getPrevSibling(); if (startElement != null && endElement != null) { if (startElement.getTextRange().getStartOffset() > endElement.getTextRange().getStartOffset()) return PsiElement.EMPTY_ARRAY; startElement = findClosestParentAfterLineBreak(startElement); if (startElement != null) { endElement = findClosestParentBeforeLineBreak(endElement); if (endElement != null) { PsiElement commonParent = startElement.getParent(); if (endElement.getParent() == commonParent) { if (startElement == endElement) return new PsiElement[] {startElement}; return new PsiElement[] {startElement, endElement}; } } } } return PsiElement.EMPTY_ARRAY; }
private static void uncommentRange(Document document, int startOffset, int endOffset, @Nonnull 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()); }
static CommentContext tryParseCommentContext(@Nullable Commenter langCommenter, @Nonnull CharSequence chars, int offset, int lineStartOffset) { final boolean isInsideCommentLikeCode = langCommenter instanceof CodeDocumentationAwareCommenter; if (!isInsideCommentLikeCode) { return new CommentContext(); } final CodeDocumentationAwareCommenter commenter = (CodeDocumentationAwareCommenter)langCommenter; int commentStartOffset = CharArrayUtil.shiftForward(chars, lineStartOffset, " \t"); boolean docStart = commenter.getDocumentationCommentPrefix() != null && CharArrayUtil.regionMatches(chars, commentStartOffset, commenter.getDocumentationCommentPrefix()); boolean cStyleStart = commenter.getBlockCommentPrefix() != null && CharArrayUtil.regionMatches(chars, commentStartOffset, commenter.getBlockCommentPrefix()); boolean docAsterisk = commenter.getDocumentationCommentLinePrefix() != null && CharArrayUtil.regionMatches(chars, commentStartOffset, commenter.getDocumentationCommentLinePrefix()); final int firstNonSpaceInLine = CharArrayUtil.shiftForward(chars, offset, " \t"); boolean slashSlash = commenter.getLineCommentPrefix() != null && CharArrayUtil.regionMatches(chars, commentStartOffset, commenter.getLineCommentPrefix()) && firstNonSpaceInLine < chars.length() && chars.charAt(firstNonSpaceInLine) != '\n'; return new CommentContext(commenter, docStart, cStyleStart, docAsterisk, slashSlash, commentStartOffset); }
@Nullable public static Couple<String> getBlockPrefixSuffixPair(@NotNull PsiElement comment) { final Commenter commenter = LanguageCommenters.INSTANCE.forLanguage(comment.getLanguage()); if (commenter != null) { final String prefix = commenter.getBlockCommentPrefix(); final String suffix = commenter.getBlockCommentSuffix(); if (prefix != null || suffix != null) { return Couple.of(StringUtil.notNullize(prefix), StringUtil.notNullize(suffix)); } } return null; }
@Override public boolean isOneLine() { final Commenter commenter = LanguageCommenters.INSTANCE.forLanguage(myHost.getLanguage()); if (commenter instanceof CodeDocumentationAwareCommenter) { return myHost.getTokenType() == ((CodeDocumentationAwareCommenter) commenter).getLineCommentTokenType(); } return false; }
private static int getCommentStart(Editor editor, PsiFile psiFile, int line) { int offset = editor.getDocument().getLineStartOffset(line); CharSequence chars = editor.getDocument().getCharsSequence(); offset = CharArrayUtil.shiftForward(chars, offset, " \t"); final Commenter commenter = findCommenter(editor, psiFile, 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; }
private static void uncommentLine(Block block, int line) { Document document = block.editor.getDocument(); Commenter commenter = block.commenters[line - block.startLine]; if (commenter == null) commenter = findCommenter(block.editor, block.psiFile, line); if (commenter == null) return; final int startOffset = block.startOffsets[line - block.startLine]; if (commenter instanceof SelfManagingCommenter) { final SelfManagingCommenter selfManagingCommenter = (SelfManagingCommenter)commenter; selfManagingCommenter.uncommentLine(line, startOffset, document, block.commenterStateMap.get(selfManagingCommenter)); return; } final int endOffset = block.endOffsets[line - block.startLine]; if (startOffset == endOffset) { return; } RangeMarker marker = endOffset > startOffset ? block.editor.getDocument().createRangeMarker(startOffset, endOffset) : null; try { if (doUncommentLine(line, document, commenter, startOffset, endOffset)) return; if (marker != null) { CommentByBlockCommentHandler.processDocument(document, marker, commenter, false); } } finally { if (marker != null) { marker.dispose(); } } }
@Override protected boolean isValidFor(@NotNull Project project, @NotNull Editor editor, @NotNull Caret caret, @NotNull final PsiFile file) { final FileType fileType = file.getFileType(); if (fileType instanceof AbstractFileType) { return ((AbstractFileType)fileType).getCommenter() != null; } Commenter commenter = LanguageCommenters.INSTANCE.forLanguage(file.getLanguage()); if (commenter == null) commenter = LanguageCommenters.INSTANCE.forLanguage(file.getViewProvider().getBaseLanguage()); if (commenter == null) return false; return commenter.getBlockCommentPrefix() != null && commenter.getBlockCommentSuffix() != null; }
@Nullable private static Commenter findCommenter(PsiFile file, Editor editor, Caret caret) { final FileType fileType = file.getFileType(); if (fileType instanceof AbstractFileType) { return ((AbstractFileType)fileType).getCommenter(); } Language lang = PsiUtilBase.getLanguageInEditor(caret, file.getProject()); return getCommenter(file, editor, lang, lang); }
static TextRange processDocument(Document document, RangeMarker marker, Commenter commenter, boolean escape) { if (commenter instanceof EscapingCommenter) { if (escape) { ((EscapingCommenter)commenter).escape(document, marker); } else { ((EscapingCommenter)commenter).unescape(document, marker); } } return TextRange.create(marker.getStartOffset(), marker.getEndOffset()); }
@Override public boolean canSelect(PsiElement e) { if (e instanceof PsiComment) { final Commenter commenter = LanguageCommenters.INSTANCE.forLanguage(e.getLanguage()); if (!(commenter instanceof CodeDocumentationAwareCommenter)) return true; return !((CodeDocumentationAwareCommenter) commenter).isDocumentationComment((PsiComment)e); } return false; }
private static boolean hasAnyDocAwareCommenters() { final Collection<Language> languages = Language.getRegisteredLanguages(); for (Language language : languages) { final Commenter commenter = LanguageCommenters.INSTANCE.forLanguage(language); if (commenter instanceof CodeDocumentationAwareCommenter) { final CodeDocumentationAwareCommenter docCommenter = (CodeDocumentationAwareCommenter)commenter; if (docCommenter.getDocumentationCommentLinePrefix() != null) { return true; } } } return false; }
@Override public void applyFix(@NotNull final Project project, @NotNull final ProblemDescriptor descriptor) { final PsiElement psiElement = descriptor.getPsiElement(); final PsiFile psiFile = psiElement.getContainingFile(); new WriteCommandAction(project, psiFile) { @Override protected void run(@NotNull final Result result) throws Throwable { final XmlTag tag = PsiTreeUtil.getParentOfType(psiElement, XmlTag.class); if (tag == null) return; final Language language = psiFile.getViewProvider().getBaseLanguage(); final Commenter commenter = LanguageCommenters.INSTANCE.forLanguage(language); if (commenter == null) return; final PsiFile tempFile = PsiFileFactory.getInstance(project).createFileFromText("dummy", language.getAssociatedFileType(), commenter.getBlockCommentPrefix() + "@declare id=\"" + myId + "\"" + commenter.getBlockCommentSuffix() + "\n"); final XmlTag parent = tag.getParentTag(); if (parent != null && parent.isValid()) { final XmlTag[] tags = parent.getSubTags(); if (tags.length > 0) { final PsiFile psi = tempFile.getViewProvider().getPsi(language); if (psi != null) { final PsiElement element = psi.findElementAt(1); if (element instanceof PsiComment) { parent.getNode().addChild(element.getNode(), tags[0].getNode()); } } } } } }.execute(); }
private static boolean isLineComment(Commenter commenter, PsiComment comment, Document doc) { final String lineCommentPrefix = commenter.getLineCommentPrefix(); if (lineCommentPrefix != null) { return comment.getText().startsWith(lineCommentPrefix); } final TextRange textRange = comment.getTextRange(); return doc.getLineNumber(textRange.getStartOffset()) == doc.getLineNumber(textRange.getEndOffset()); }
private static Commenter getCommenter(FileType fileType) { if (fileType instanceof LanguageFileType) { return LanguageCommenters.INSTANCE.forLanguage(((LanguageFileType)fileType).getLanguage()); } return null; }
private static boolean isSupportedType(FileType type) { if (type.isBinary() || type.getName().indexOf("IDEA") >= 0 || "GUI_DESIGNER_FORM".equals(type.getName())) { return false; } else { Commenter commenter = getCommenter(type); boolean hasComment = commenter != null && (commenter.getLineCommentPrefix() != null || commenter.getBlockCommentPrefix() != null); if (!hasComment) { return false; } if (type.equals(StdFileTypes.DTD)) { return true; } if (type.equals(StdFileTypes.HTML)) { return true; } if (type.equals(StdFileTypes.XHTML)) { return true; } if (type.equals(StdFileTypes.PROPERTIES)) { return true; } if ("JavaScript".equals(type.getName())) { return true; } return CopyrightUpdaters.INSTANCE.forFileType(type) != null; } }
@Nullable public static Pair<String, String> getBlockPrefixSuffixPair(PsiElement comment) { final Commenter commenter = LanguageCommenters.INSTANCE.forLanguage(comment.getLanguage()); if (commenter != null) { final String prefix = commenter.getBlockCommentPrefix(); final String suffix = commenter.getBlockCommentSuffix(); if (prefix != null || suffix != null) { return Pair.create(StringUtil.notNullize(prefix), StringUtil.notNullize(suffix)); } } return null; }
@Override public TextRange surroundElements(@NotNull Project project, @NotNull Editor editor, @NotNull PsiElement[] elements) throws IncorrectOperationException { if (elements.length == 0) return null; PsiElement firstElement = elements[0]; PsiElement lastElement = elements[elements.length - 1]; PsiFile psiFile = firstElement.getContainingFile(); Language language = psiFile.getLanguage(); Commenter commenter = LanguageCommenters.INSTANCE.forLanguage(language); if (commenter == null) return null; String linePrefix = commenter.getLineCommentPrefix(); if (linePrefix == null) return null; int prefixLength = linePrefix.length(); int startOffset = firstElement.getTextRange().getStartOffset(); int endOffset = lastElement.getTextRange().getEndOffset(); int delta = 0; TextRange rangeToSelect = new TextRange(startOffset, startOffset); String startText = myProvider.getStartString(); int descPos = startText.indexOf("?"); if (descPos >= 0) { startText = startText.replace("?", DEFAULT_DESC_TEXT); rangeToSelect = new TextRange(startOffset + descPos, startOffset + descPos + DEFAULT_DESC_TEXT.length()); } String startString = linePrefix + startText + "\n"; String endString = "\n" + linePrefix + myProvider.getEndString(); editor.getDocument().insertString(endOffset, endString); delta += endString.length(); editor.getDocument().insertString(startOffset, startString); delta += startString.length(); rangeToSelect = rangeToSelect.shiftRight(prefixLength); PsiDocumentManager documentManager = PsiDocumentManager.getInstance(project); documentManager.commitDocument(documentManager.getDocument(psiFile)); adjustLineIndent(project, psiFile, language, new TextRange(endOffset + delta - endString.length(), endOffset + delta)); adjustLineIndent(project, psiFile, language, new TextRange(startOffset, startOffset + startString.length())); return rangeToSelect; }
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; }
public void doDefaultCommenting(final Commenter commenter) { DocumentUtil.executeInBulk( myDocument, myEndLine - myStartLine >= Registry.intValue("comment.by.line.bulk.lines.trigger"), new Runnable() { @Override public void run() { for (int line = myEndLine; line >= myStartLine; line--) { int offset = myDocument.getLineStartOffset(line); commentLine(line, offset, commenter); } } }); }