String (@NotNull PsiFile file, @NotNull Document document, int caretOffset, int lineNumber, @NotNull String fragmentIndent) { PsiElement nonWS = PyUtil.findNextAtOffset(file, caretOffset, PsiWhiteSpace.class); if (nonWS != null) { final IElementType nonWSType = nonWS.getNode().getElementType(); if (nonWSType == PyTokenTypes.ELSE_KEYWORD || nonWSType == PyTokenTypes.ELIF_KEYWORD || nonWSType == PyTokenTypes.EXCEPT_KEYWORD || nonWSType == PyTokenTypes.FINALLY_KEYWORD) { lineNumber -= 1; nonWS = PyUtil.findNextAtOffset(file, getLineStartSafeOffset(document, lineNumber), PsiWhiteSpace.class); } } if (nonWS != null && document.getLineNumber(nonWS.getTextOffset()) == lineNumber) { return PyIndentUtil.getLineIndent(document, lineNumber); } final int lineStartOffset = getLineStartSafeOffset(document, lineNumber); final PsiElement ws = file.findElementAt(lineStartOffset); final String userIndent = document.getText(TextRange.create(lineStartOffset, caretOffset)); final PyStatementList statementList = findEmptyStatementListNearby(file, lineStartOffset); if (statementList != null) { return PyIndentUtil.getElementIndent(statementList); } final String smallestIndent = ws == null? "" : PyIndentUtil.getElementIndent(ws); final PyStatementListContainer parentBlock = PsiTreeUtil.getParentOfType(ws, PyStatementListContainer.class); final PyStatementListContainer deepestBlock = getDeepestPossibleParentBlock(file, caretOffset); final String greatestIndent; if (deepestBlock != null && (parentBlock == null || PsiTreeUtil.isAncestor(parentBlock, deepestBlock, true))) { greatestIndent = PyIndentUtil.getElementIndent(deepestBlock.getStatementList()); } else { greatestIndent = smallestIndent; } if (caretOffset == lineStartOffset && fragmentIndent.startsWith(smallestIndent) && greatestIndent.startsWith(fragmentIndent)) { return fragmentIndent; } if (smallestIndent.startsWith(userIndent)) { return smallestIndent; } if (userIndent.startsWith(greatestIndent)) { return greatestIndent; } return userIndent; }