*/
private Tuple<String, Boolean> autoIndentNewline(IDocument document, int length, String text, int offset)
throws BadLocationException {
if (offset > 0) {
PySelection selection = new PySelection(document, offset);
String lineWithoutComments = selection.getLineContentsToCursor(true, true);
Tuple<Integer, Boolean> tup = determineSmartIndent(offset, document, prefs);
int smartIndent = tup.o1;
boolean isInsidePar = tup.o2;
if (lineWithoutComments.length() > 0) {
//ok, now let's see the auto-indent
int curr = lineWithoutComments.length() - 1;
char lastChar = lineWithoutComments.charAt(curr);
//we dont want whitespaces
while (curr > 0 && Character.isWhitespace(lastChar)) {
curr--;
lastChar = lineWithoutComments.charAt(curr);
}
//we have to check if smartIndent is -1 because otherwise we are inside some bracket
if (smartIndent == -1 && !isInsidePar && StringUtils.isClosingPeer(lastChar)) {
//ok, not inside brackets
PythonPairMatcher matcher = new PythonPairMatcher(StringUtils.BRACKETS);
int bracketOffset = selection.getLineOffset() + curr;
IRegion region = matcher.match(document, bracketOffset + 1);
if (region != null) {
if (!PySelection.endsInSameLine(document, region)) {
//we might not have a match if there is an error in the program...
//e.g. a single ')' without its counterpart.
int openingBracketLine = document.getLineOfOffset(region.getOffset());
String openingBracketLineStr = PySelection.getLine(document, openingBracketLine);
int first = PySelection.getFirstCharPosition(openingBracketLineStr);
String initial = getCharsBeforeNewLine(text);
text = initial + openingBracketLineStr.substring(0, first);
return new Tuple<String, Boolean>(text, isInsidePar);
}
}
} else if (smartIndent == -1 && lastChar == ':') {
//we have to check if smartIndent is -1 because otherwise we are in a dict
//ok, not inside brackets
text = indentBasedOnStartingScope(text, selection, false);
return new Tuple<String, Boolean>(text, isInsidePar);
}
}
String trimmedLine = lineWithoutComments.trim();
if (smartIndent >= 0
&& (StringUtils.hasOpeningBracket(trimmedLine) || StringUtils.hasClosingBracket(trimmedLine))) {
return new Tuple<String, Boolean>(makeSmartIndent(text, smartIndent), isInsidePar);
}
//let's check for dedents...
if (PySelection.startsWithDedentToken(trimmedLine)) {
if (lineWithoutComments.endsWith("\\")) {
//Okay, we're in something as return \, where the next line will be part of this statement, so, don't really
//go back an indent, but go up an indent.
return new Tuple<String, Boolean>(text + prefs.getIndentationString(), isInsidePar);
}
return new Tuple<String, Boolean>(dedent(text), isInsidePar);
}
boolean indentBasedOnStartingScope = false;
try {
if (PySelection.containsOnlyWhitespaces(selection.getLineContentsFromCursor())) {
indentBasedOnStartingScope = true;
}
} catch (BadLocationException e) {
//(end of the file)
indentBasedOnStartingScope = true;
}
if (indentBasedOnStartingScope) {
String lineContentsToCursor = selection.getLineContentsToCursor();
String trimmed = lineContentsToCursor.trim();
if (trimmed.length() == 0) {
return new Tuple<String, Boolean>(indentBasedOnStartingScope(text, selection, false), isInsidePar);
} else {
boolean endsWithTrippleSingle = trimmed.endsWith("'''");
if (endsWithTrippleSingle || trimmed.endsWith("\"\"\"")) {
//ok, as we're out of a string scope at this point, this means we just closed a string, so,
//we should go back to indent based on starting scope.
if (endsWithTrippleSingle) {
int cursorLine = -1;
try {
ParsingUtils parsingUtils = ParsingUtils.create(selection.getDoc(), true);
int cursorOffset = selection.getAbsoluteCursorOffset();
char c;
do {
cursorOffset--;
c = parsingUtils.charAt(cursorOffset);
} while (Character.isWhitespace(c));
int startOffset = parsingUtils.eatLiteralsBackwards(null, cursorOffset);
cursorLine = selection.getLineOfOffset(startOffset);
} catch (Exception e) {
//may throw error if not balanced or if the char we're at is not a ' or "
}
if (cursorLine == -1) {
cursorLine = selection.getCursorLine();
}
return new Tuple<String, Boolean>(indentBasedOnStartingScope(text, new PySelection(
selection.getDoc(), cursorLine, 0), false), isInsidePar);
}
}
}
}