in ruta-ep-ide-ui/src/main/java/org/apache/uima/ruta/ide/ui/text/RutaAutoEditStrategy.java [385:599]
private String calcLineIndent(IDocument d, int line, boolean newLine, int offset)
throws BadLocationException {
boolean isDocumentEnd = (offset == d.getLength());
// STRINGS
if (newLine) {
// if we wrap string
if (getRegionType(d, offset) == RutaPartitions.RUTA_STRING) {
int realLine = d.getLineOfOffset(offset);
String curIndent = getLineIndent(d, realLine);
// if we just closed string
if (d.getChar(offset - 1) != '"') {
// if we are fully in string
if (getRegionType(d, d.getLineOffset(realLine)) == RutaPartitions.RUTA_STRING) {
return curIndent;
}
// if we first time wrap string
return curIndent + getIndent();
}
}
} else {
// don't correct strings
if (getRegionType(d, d.getLineOffset(line)) == RutaPartitions.RUTA_STRING) {
return getLineIndent(d, line); // notice, that we don't use
// null
}
}
// LINE JOINING
if (newLine) {
int realLine = d.getLineOfOffset(offset);
if (line > 0) {
String previousLine = "";
if (realLine == line - 1) {
int start = d.getLineOffset(realLine);
previousLine = d.get(start, offset - start);
} else
previousLine = getDocumentLine(d, line - 1);
if (previousLine.trim().endsWith("\\")) {
String prePreviousLine = getDocumentLine(d, line - 2);
if (prePreviousLine.trim().endsWith("\\"))
return getLineIndent(d, line - 1);
return getLineIndent(d, line - 1) + getIndent() + getIndent();
}
if (line > 1) {
String prePreviousLine = getDocumentLine(d, line - 2);
if (prePreviousLine.trim().endsWith("\\")) {
// find start
int t = line - 2;
while (t > 0 && getDocumentLine(d, t - 1).trim().endsWith("\\")) {
t--;
}
return getLineIndent(d, t);
}
}
}
} else {
/*
* If this line is explicitly joined: If the previous line was also joined, line it up with
* that one, otherwise add two 'shiftwidth'
*/
if (line > 0) {
String previousLine = getDocumentLine(d, line - 1);
if (previousLine.trim().endsWith("\\")) {
if (line > 1) {
String prePreviousLine = getDocumentLine(d, line - 2);
if (prePreviousLine.trim().endsWith("\\"))
return getLineIndent(d, line - 1);
}
return getLineIndent(d, line - 1) + getIndent() + getIndent();
}
}
}
// Search backwards for the previous non-empty line.
int lastNonEmptyLine = getLastNonEmptyLine(d, line - 1);
if (lastNonEmptyLine < 0) {
// This is the first non-empty line, use zero indent.
return "";
}
// first check, if we not inside string, if yes, jump to start
ITypedRegion region = TextUtilities.getPartition(d, fPartitioning,
d.getLineOffset(lastNonEmptyLine), true);
if (region.getType() == RutaPartitions.RUTA_STRING) {
lastNonEmptyLine = d.getLineOfOffset(region.getOffset());
}
// If the previous line is inside parenthesis, use the indent of the
// starting line.
int plnumstart;
String previousLineIndent = "";
int pairOffset = searchPair(d, d.getLineOffset(lastNonEmptyLine), false, '(', ')', true, true);
if (pairOffset >= 0) {
plnumstart = d.getLineOfOffset(pairOffset);
previousLineIndent = getLineIndent(d, plnumstart);
} else {
plnumstart = lastNonEmptyLine;
previousLineIndent = getLineIndent(d, lastNonEmptyLine);
}
/*
* When inside parenthesis: If at the first line below the parenthesis add two 'shiftwidth',
* otherwise same as previous line. i = (a + b + c)
*/
int p = searchPair(d, offset - 1, false, '(', ')', true, true);
if (p >= 0) {
if (d.getLineOfOffset(p) == lastNonEmptyLine) {
// When the start is inside parenthesis, only indent one
// 'shiftwidth'.
int pp = searchPair(d, p, false, '(', ')', true, true);
if (pp >= 0)
return getLineIndent(d, lastNonEmptyLine) + getIndent();
return getLineIndent(d, lastNonEmptyLine) + getIndent() + getIndent();
}
if (d.getLineOfOffset(p) == plnumstart) {
return getLineIndent(d, lastNonEmptyLine);
}
if (d.getLineOfOffset(p) == line && !newLine)
return null;
return previousLineIndent;
}
// Get the line and remove a trailing comment.
String pline = "";
if (lastNonEmptyLine == line - 1 && newLine) {
pline = d.get(d.getLineOffset(line - 1), offset - d.getLineOffset(line - 1));
} else {
pline = getDocumentLine(d, lastNonEmptyLine);
}
int plineLen = pline.length();
int i;
for (i = 0; i < plineLen; i++) {
if (pline.charAt(i) == '#') {
pline = pline.substring(0, i);
break;
}
}
String plineTrimmed = pline.trim();
try {// If the current line begins with a keyword that lines up with
// "try"
String curLine = "";
if (lastNonEmptyLine == line - 1 && newLine) {
curLine = d.get(offset, d.getLineLength(line - 1) + d.getLineOffset(line - 1) - offset);
} else {
curLine = getDocumentLine(d, line).trim();
}
if (curLine.startsWith("except") || curLine.startsWith("finally")) {
int lnum = line - 1;
while (lnum >= 0) {
String temp = getDocumentLine(d, lnum).trim();
if (temp.startsWith("try") || temp.startsWith("except")) {
String ind = getLineIndent(d, lnum);
return ind;
}
lnum--;
}
return null;
}
// If the current line begins with a header keyword, dedent
if (curLine.startsWith("elif") || curLine.startsWith("else")) {
// Unless the previous line was a one-liner
String temp = getDocumentLine(d, lastNonEmptyLine).trim();
if (temp.startsWith("for") || temp.startsWith("if") || temp.startsWith("try")
|| temp.startsWith("while")) {
return previousLineIndent;
}
int sline = findIndentStart(d, lastNonEmptyLine);
String reqIndent = getLineIndent(d, sline);
return reqIndent;
}
} catch (BadLocationException e) {
// do nothing, we just don't have current line
}
// If the previous line was a stop-execution statement...
String regex = "^\\s*(break|continue|raise|pass|return)(\\s+.*$|$)";
if (Pattern.matches(regex, plineTrimmed)) {
// find indent
int sline = findIndentStart(d, lastNonEmptyLine);
String reqIndent = getLineIndent(d, sline);
if (newLine || isDocumentEnd
|| (getPhysicalLength(getLineIndent(d, line)) > getPhysicalLength(reqIndent))) {
return reqIndent;
}
// trust the user
return null;
}
// If the previous line ended with a colon, indent this line
if (plineTrimmed.endsWith(":"))
return previousLineIndent + getIndent();
if (pairOffset >= 0 && newLine) {
return previousLineIndent;
}
// after-string
int prevLine = getLastNonEmptyLine(d, line - 1);
if (getRegionType(d, d.getLineOffset(prevLine)) == RutaPartitions.RUTA_STRING)
return previousLineIndent;
return null;
}