List<TextRange> (@NotNull final PsiElement e, @NotNull final CharSequence editorText, final int cursorOffset, @NotNull final Editor editor) { final VirtualFile file = e.getContainingFile().getVirtualFile(); final FileType fileType = file == null? null : file.getFileType(); if (fileType == null) return super.select(e, editorText, cursorOffset, editor); final int textLength = editorText.length(); final TextRange totalRange = e.getTextRange(); final HighlighterIterator iterator = editor.getHighlighter().createIterator(totalRange.getStartOffset()); final BraceMatcher braceMatcher = BraceMatchingUtil.getBraceMatcher(fileType, iterator); final ArrayList<TextRange> result = new ArrayList<>(); record TokenData(int start, int end, IElementType type) {} final Deque<TokenData> stack = new ArrayDeque<>(); while (!iterator.atEnd() && iterator.getStart() < totalRange.getEndOffset()) { final TokenData last; if (braceMatcher.isLBraceToken(iterator, editorText, fileType)) { stack.addLast(new TokenData(iterator.getStart(), iterator.getEnd(), iterator.getTokenType())); } else if (braceMatcher.isRBraceToken(iterator, editorText, fileType) && !stack.isEmpty() && braceMatcher.isPairBraces((last = stack.getLast()).type, iterator.getTokenType())) { stack.removeLast(); result.addAll(expandToWholeLine(editorText, new TextRange(last.start, iterator.getEnd()))); int bodyStart = last.end; int bodyEnd = iterator.getStart(); while (bodyStart < textLength && Character.isWhitespace(editorText.charAt(bodyStart))) bodyStart++; while (bodyEnd > 0 && bodyStart < bodyEnd && Character.isWhitespace(editorText.charAt(bodyEnd - 1))) bodyEnd--; result.addAll(expandToWholeLine(editorText, new TextRange(bodyStart, bodyEnd))); } iterator.advance(); } result.add(e.getTextRange()); return result; }