private String calcLineIndent()

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;
  }