private void analyseDocument(Document document, int lineNum, PythonIndentation indentationLogic) throws BadLocationException { Element map = document.getDefaultRootElement(); int endPos = map.getElement(lineNum).getEndOffset(); indentationLogic.reset(); indentationLogic.addText(document.getText(0, endPos)); }
private void handleDecreaseIndent(int line, Element elem, StyledDocument doc) throws BadLocationException { int start = elem.getStartOffset(); int end = elem.getEndOffset() - 1; doc.getText(start, end - start, segLine); int i = segLine.offset; end = i + segLine.count; if (end > i) { String leadingWS = PythonIndentation.getLeadingWhitespace(doc, start, end - start); int toRemove = indentationLogic.checkDedent(leadingWS, line + 1); doc.remove(start, toRemove); } }
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()); } }