Example #1
0
    private void insertNewlineWithAutoIndent(JTextComponent text) {
      try {
        int caretPos = text.getCaretPosition();
        StyledDocument doc = (StyledDocument) text.getDocument();
        Element map = doc.getDefaultRootElement();
        int lineNum = map.getElementIndex(caretPos);
        Element line = map.getElement(lineNum);
        int start = line.getStartOffset();
        int end = line.getEndOffset() - 1;
        int len = end - start;
        String s = doc.getText(start, len);

        String leadingWS = PythonIndentation.getLeadingWhitespace(doc, start, caretPos - start);
        StringBuffer sb = new StringBuffer("\n");
        sb.append(leadingWS);
        // TODO better control over automatic indentation
        indentationLogic.checkIndent(leadingWS, lineNum + 1);

        // If there is only whitespace between the caret and
        // the EOL, pressing Enter auto-indents the new line to
        // the same place as the previous line.
        int nonWhitespacePos = PythonIndentation.atEndOfLine(doc, caretPos, start, s, len);
        if (nonWhitespacePos == -1) {
          if (leadingWS.length() == len) {
            // If the line was nothing but whitespace, select it
            // so its contents get removed.
            text.setSelectionStart(start);
          } else {
            // Select the whitespace between the caret and the EOL
            // to remove it
            text.setSelectionStart(caretPos);
          }
          text.setSelectionEnd(end);
          text.replaceSelection(sb.toString());
          // auto-indentation for python statements like if, while, for, try,
          // except, def, class and auto-deindentation for break, continue,
          // pass, return
          analyseDocument(doc, lineNum, indentationLogic);
          // auto-completion: add colon if it is obvious
          if (indentationLogic.shouldAddColon()) {
            doc.insertString(caretPos, ":", null);
            indentationLogic.setLastLineEndsWithColon();
          }
          int lastLineChange = indentationLogic.shouldChangeLastLineIndentation();
          int nextLineChange = indentationLogic.shouldChangeNextLineIndentation();
          if (lastLineChange != 0) {
            Debug.log(5, "change line %d indentation by %d columns", lineNum + 1, lastLineChange);
            changeIndentation((DefaultStyledDocument) doc, lineNum, lastLineChange);
            // nextLineChange was determined based on indentation of last line before
            // the change
            nextLineChange += lastLineChange;
          }
          if (nextLineChange != 0) {
            Debug.log(5, "change line %d indentation by %d columns", lineNum + 2, nextLineChange);
            changeIndentation((DefaultStyledDocument) doc, lineNum + 1, nextLineChange);
          }
        } // If there is non-whitespace between the caret and the
        // EOL, pressing Enter takes that text to the next line
        // and auto-indents it to the same place as the last
        // line. Additional auto-indentation or dedentation for
        // specific python statements is only done for the next line.
        else {
          text.setCaretPosition(nonWhitespacePos);
          doc.insertString(nonWhitespacePos, sb.toString(), null);
          analyseDocument(doc, lineNum, indentationLogic);
          int nextLineChange = indentationLogic.shouldChangeNextLineIndentation();
          if (nextLineChange != 0) {
            Debug.log(5, "change line %d indentation by %d columns", lineNum + 2, nextLineChange);
            changeIndentation((DefaultStyledDocument) doc, lineNum + 1, nextLineChange);
          }
        }

      } catch (BadLocationException ble) {
        text.replaceSelection("\n");
        Debug.error(me + "Problem while inserting new line with auto-indent\n%s", ble.getMessage());
      }
    }