void Indenter::reindent(QTextDocument *doc, const QTextCursor &cursor, const TextEditor::TabSettings &tabSettings) { if (cursor.hasSelection()) { QTextBlock block = doc->findBlock(cursor.selectionStart()); const QTextBlock end = doc->findBlock(cursor.selectionEnd()).next(); // skip empty blocks while (block.isValid() && block != end) { QString bt = block.text(); if (tabSettings.firstNonSpace(bt) < bt.size()) break; indentBlock(doc, block, QChar::Null, tabSettings); block = block.next(); } int previousIndentation = tabSettings.indentationColumn(block.text()); indentBlock(doc, block, QChar::Null, tabSettings); int currentIndentation = tabSettings.indentationColumn(block.text()); int delta = currentIndentation - previousIndentation; block = block.next(); while (block.isValid() && block != end) { tabSettings.reindentLine(block, delta); block = block.next(); } } else { indentBlock(doc, cursor.block(), QChar::Null, tabSettings); } }
void Indenter::parsePreviousLine( const TextEditor::TabSettings &settings, const QString &previousLine, const QTextBlock &previousBlock, int &indentation) const { // TODO: replace this dirty code with true AST-based indentation Internal::Scanner sc(previousLine.constData(), previousLine.length()); for (;;) { Internal::FormatToken tk = sc.read(); if (tk.format() == Internal::Format_KEYWORD) { QString value = sc.value(tk); if (JUMP_STATEMENTS_SET.contains(value)) { indentation = qMax<int>(0, indentation - TAB_SIZE); } else if (BACKSTEP_KEYWORDS_SET.contains(value)) { indentation = qMax<int>(0, indentation - TAB_SIZE); settings.reindentLine(previousBlock, -TAB_SIZE); } } if (tk.format() != Internal::Format_WHITESPACE) { break; } } }