void (@NotNull Project project, @NotNull Editor editor, @NotNull Caret caret, @NotNull PsiFile file) { file = file.getViewProvider().getPsi(file.getViewProvider().getBaseLanguage()); PsiElement context = InjectedLanguageManager.getInstance(file.getProject()).getInjectionHost(file); if (context != null && shouldCommentInHostFile(file, context)) { file = context.getContainingFile(); editor = editor instanceof EditorWindow ? ((EditorWindow)editor).getDelegate() : editor; caret = caret instanceof InjectedCaret ? ((InjectedCaret)caret).getDelegate() : caret; } Document document = editor.getDocument(); boolean hasSelection = caret.hasSelection(); int startOffset = caret.getSelectionStart(); int endOffset = caret.getSelectionEnd(); FoldRegion fold = editor.getFoldingModel().getCollapsedRegionAtOffset(startOffset); if (fold != null && fold.shouldNeverExpand() && fold.getStartOffset() == startOffset && fold.getEndOffset() == endOffset) { // Foldings that never expand are automatically selected, so the fact it is selected must not interfere with commenter's logic hasSelection = false; } if (document.getTextLength() == 0) return; while (true) { int firstLineStart = DocumentUtil.getLineStartOffset(startOffset, document); FoldRegion collapsedAt = editor.getFoldingModel().getCollapsedRegionAtOffset(firstLineStart - 1); if (collapsedAt == null || isInvisibleRegionAtLineStart(collapsedAt) /* rendered doc case */) break; int regionStartOffset = collapsedAt.getStartOffset(); if (regionStartOffset >= startOffset) break; startOffset = regionStartOffset; } if (!hasSelection || !DocumentUtil.isAtLineStart(endOffset, document)) { while (true) { int lastLineEnd = DocumentUtil.getLineEndOffset(endOffset, document); FoldRegion collapsedAt = editor.getFoldingModel().getCollapsedRegionAtOffset(lastLineEnd); if (collapsedAt == null) break; int regionEndOffset = collapsedAt.getEndOffset(); if (regionEndOffset <= endOffset) break; endOffset = regionEndOffset; } } int startLine = document.getLineNumber(startOffset); int endLine = document.getLineNumber(endOffset); if (endLine > startLine && document.getLineStartOffset(endLine) == endOffset) { endLine--; } Block lastBlock = myBlocks.isEmpty() ? null : myBlocks.get(myBlocks.size() - 1); Block currentBlock; if (lastBlock == null || lastBlock.editor != editor || lastBlock.psiFile != file || startLine > (lastBlock.endLine + 1)) { currentBlock = new Block(); currentBlock.editor = editor; currentBlock.psiFile = file; currentBlock.startLine = startLine; myBlocks.add(currentBlock); } else { currentBlock = lastBlock; } currentBlock.carets.add(caret); currentBlock.endLine = endLine; boolean wholeLinesSelected = !hasSelection || startOffset == document.getLineStartOffset(document.getLineNumber(startOffset)) && endOffset == document.getLineEndOffset(document.getLineNumber(endOffset - 1)) + 1; boolean startingNewLineComment = !hasSelection && DocumentUtil.isLineEmpty(document, document.getLineNumber(startOffset)) && !Objects .equals(IdeActions.ACTION_COMMENT_LINE, ActionManagerEx.getInstanceEx().getPrevPreformedActionId()); currentBlock.caretUpdate = startingNewLineComment ? CaretUpdate.PUT_AT_COMMENT_START : !hasSelection ? (AdvancedSettings.getBoolean("editor.comment.line.caret.down") ? CaretUpdate.SHIFT_DOWN : null) : wholeLinesSelected ? CaretUpdate.RESTORE_SELECTION : null; }