public void actionPerformed(JTextComponent text) { indentationLogic = ((EditorPane) text).getIndentationLogic(); StyledDocument doc = (StyledDocument) text.getDocument(); Element map = doc.getDefaultRootElement(); Caret c = text.getCaret(); int dot = c.getDot(); int mark = c.getMark(); int line1 = map.getElementIndex(dot); if (dot != mark) { int line2 = map.getElementIndex(mark); int begin = Math.min(line1, line2); int end = Math.max(line1, line2); Element elem; try { for (line1 = begin; line1 < end; line1++) { elem = map.getElement(line1); handleDecreaseIndent(line1, elem, doc); } elem = map.getElement(end); int start = elem.getStartOffset(); if (Math.max(c.getDot(), c.getMark()) != start) { handleDecreaseIndent(end, elem, doc); } } catch (BadLocationException ble) { Debug.error(me + "Problem while de-indenting line\n%s", ble.getMessage()); UIManager.getLookAndFeel().provideErrorFeedback(text); } } else { Element elem = map.getElement(line1); try { handleDecreaseIndent(line1, elem, doc); } catch (BadLocationException ble) { Debug.error(me + "Problem while de-indenting line\n%s", ble.getMessage()); UIManager.getLookAndFeel().provideErrorFeedback(text); } } }
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()); } }