/** * 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(); }