Пример #1
0
void CppQtStyleIndenter::indentBlock(QTextDocument *doc,
                                     const QTextBlock &block,
                                     const QChar &typedChar,
                                     const TextEditor::TabSettings &tabSettings)
{
    Q_UNUSED(doc)

    CppTools::QtStyleCodeFormatter codeFormatter(tabSettings, codeStyleSettings());

    codeFormatter.updateStateUntil(block);
    int indent;
    int padding;
    codeFormatter.indentFor(block, &indent, &padding);

    if (isElectricCharacter(typedChar)) {
        // : should not be electric for labels
        if (typedChar == QLatin1Char(':') && !colonIsElectric(block.text()))
            return;

        // only reindent the current line when typing electric characters if the
        // indent is the same it would be if the line were empty
        int newlineIndent;
        int newlinePadding;
        codeFormatter.indentForNewLineAfter(block.previous(), &newlineIndent, &newlinePadding);
        if (tabSettings.indentationColumn(block.text()) != newlineIndent + newlinePadding)
            return;
    }

    tabSettings.indentLine(block, indent + padding, padding);
}
Пример #2
0
void GLSLIndenter::indentBlock(QTextDocument *doc,
                               const QTextBlock &block,
                               const QChar &typedChar,
                               const TextEditor::TabSettings &tabSettings)
{
    Q_UNUSED(doc)

    // TODO: do something with it
    CppTools::QtStyleCodeFormatter codeFormatter(tabSettings,
              CppTools::CppToolsSettings::instance()->cppCodeStyle()->codeStyleSettings());

    codeFormatter.updateStateUntil(block);
    int indent;
    int padding;
    codeFormatter.indentFor(block, &indent, &padding);

    // only reindent the current line when typing electric characters if the
    // indent is the same it would be if the line were empty
    if (isElectricCharacter(typedChar)) {
        int newlineIndent;
        int newlinePadding;
        codeFormatter.indentForNewLineAfter(block.previous(), &newlineIndent, &newlinePadding);
        if (tabSettings.indentationColumn(block.text()) != newlineIndent + newlinePadding)
            return;
    }

    tabSettings.indentLine(block, indent + padding, padding);
}
Пример #3
0
void CMakeIndenter::indentBlock(QTextDocument *doc, const QTextBlock &block, const QChar &typedChar, const TextEditor::TabSettings &tabSettings)
{
    Q_UNUSED(doc)
    Q_UNUSED(typedChar)

    QTextBlock previousBlock = block.previous();
    // find the next previous block that is non-empty (contains non-whitespace characters)
    while (previousBlock.isValid() && lineIsEmpty(previousBlock.text()))
        previousBlock = previousBlock.previous();
    if (previousBlock.isValid()) {
        const QString previousLine = previousBlock.text();
        const QString currentLine = block.text();
        int indentation = tabSettings.indentationColumn(previousLine);

        if (lineStartsBlock(previousLine))
            indentation += tabSettings.m_indentSize;
        if (lineEndsBlock(currentLine))
            indentation = qMax(0, indentation - tabSettings.m_indentSize);

        // increase/decrease/keep the indentation level depending on if we have more opening or closing parantheses
        indentation = qMax(0, indentation + tabSettings.m_indentSize * paranthesesLevel(previousLine));

        tabSettings.indentLine(block, indentation);
    } else {
        // First line in whole document
        tabSettings.indentLine(block, 0);
    }
}
Пример #4
0
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);
    }
}
Пример #5
0
void CppQtStyleIndenter::indent(QTextDocument *doc,
                                const QTextCursor &cursor,
                                const QChar &typedChar,
                                const TextEditor::TabSettings &tabSettings)
{
    if (cursor.hasSelection()) {
        QTextBlock block = doc->findBlock(cursor.selectionStart());
        const QTextBlock end = doc->findBlock(cursor.selectionEnd()).next();

        CppTools::QtStyleCodeFormatter codeFormatter(tabSettings, codeStyleSettings());
        codeFormatter.updateStateUntil(block);

        QTextCursor tc = cursor;
        tc.beginEditBlock();
        do {
            int indent;
            int padding;
            codeFormatter.indentFor(block, &indent, &padding);
            tabSettings.indentLine(block, indent + padding, padding);
            codeFormatter.updateLineStateChange(block);
            block = block.next();
        } while (block.isValid() && block != end);
        tc.endEditBlock();
    } else {
        indentBlock(doc, cursor.block(), typedChar, tabSettings);
    }
}
Пример #6
0
void Indenter::indentBlock(const QTextBlock &block,
                           const QChar &,
                           const TextEditor::TabSettings &settings,
                           int)
{
    int indent;

    QTextBlock previous = block.previous();
    // Previous line ends on comma, ignore everything and follow the indent
    if (previous.text().endsWith(',')) {
        indent = previous.text().indexOf(QRegularExpression("\\S")) / settings.m_indentSize;
    } else {
        // Use the stored indent plus some bizarre heuristics that even myself remember how it works.
        indent = block.userState() >> 20;
        if (indent < 0) {
            while (indent == -1 && previous.isValid()) {
                indent = previous.userState() >> 20;
                previous = previous.previous();
            }
        }

        if (didBlockStart(block) && indent > 0)
            indent--;
    }

    settings.indentLine(block, indent  * settings.m_indentSize);
}
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;
        }
    }
}
/**
 * @brief Indenter::indentBlock Indents one block (usually one line) of code
 * @param block
 * @param typedChar
 * @param tabSettings An IDE tabulation settings
 *
 * Usually this method called once when you begin new line of code by pressing
 * Enter. If Indenter reimplements indent() method, than indentBlock() may be
 * called in other cases.
 */
void Indenter::indentBlock(QTextDocument */*doc*/,
                           const QTextBlock &block,
                           const QChar &/*typedChar*/,
                           const TextEditor::TabSettings &settings)
{
    QTextBlock previousBlock = block.previous();
    if (previousBlock.isValid()) {
        QString previousLine = previousBlock.text();
        int indentation = settings.indentationColumn(previousLine);

        if (isElectricLine(previousLine)) {
            indentation += TAB_SIZE;
        }
        parsePreviousLine(settings, previousLine, previousBlock, indentation);

        settings.indentLine(block, indentation);
    } else {
        // First line in whole document
        settings.indentLine(block, 0);
    }
}
Пример #9
0
void Indenter::indentBlock(QTextDocument *doc,
                           const QTextBlock &block,
                           const QChar &typedChar,
                           const TextEditor::TabSettings &tabSettings)
{
    Q_UNUSED(doc)

    QmlJSTools::QtStyleCodeFormatter codeFormatter(tabSettings);

    codeFormatter.updateStateUntil(block);
    const int depth = codeFormatter.indentFor(block);

    if (isElectricCharacter(typedChar)) {
        // only reindent the current line when typing electric characters if the
        // indent is the same it would be if the line were empty
        const int newlineIndent = codeFormatter.indentForNewLineAfter(block.previous());
        if (tabSettings.indentationColumn(block.text()) != newlineIndent)
            return;
    }

    tabSettings.indentLine(block, depth);
}
Пример #10
0
void JavaIndenter::indentBlock(QTextDocument *doc,
                                 const QTextBlock &block,
                                 const QChar &typedChar,
                                 const TextEditor::TabSettings &tabSettings)
{
    // At beginning: Leave as is.
    if (block == doc->begin())
        return;

    const int tabsize = tabSettings.m_indentSize;

    QTextBlock previous = block.previous();
    QString previousText = previous.text();
    while (previousText.trimmed().isEmpty()) {
        previous = previous.previous();
        if (previous == doc->begin())
            return;
        previousText = previous.text();
    }

    int adjust = 0;
    if (previousText.contains(QLatin1Char('{')))
        adjust = tabsize;

    if (block.text().contains(QLatin1Char('}')) || typedChar == QLatin1Char('}'))
        adjust += -tabsize;

    // Count the indentation of the previous line.
    int i = 0;
    while (i < previousText.size()) {
        if (!previousText.at(i).isSpace()) {
            tabSettings.indentLine(block, tabSettings.columnAt(previousText, i)
                                   + adjust);
            break;
        }
        ++i;
    }
}
Пример #11
0
int PythonIndenter::indentFor(const QTextBlock &block, const TextEditor::TabSettings &tabSettings)
{
    QTextBlock previousBlock = block.previous();
        if (!previousBlock.isValid())
            return 0;

        QString previousLine = previousBlock.text();
        int indentation = tabSettings.indentationColumn(previousLine);

        if (isElectricLine(previousLine))
            indentation += tabSettings.m_indentSize;
        else
            indentation = qMax<int>(0, indentation + getIndentDiff(previousLine, tabSettings));

        return indentation;
}
Пример #12
0
void GoIndenter::indentBlock(const QTextBlock &block,
                             const QChar &typedChar, const TextEditor::TabSettings &tabSettings, int cursorPositionInEditor)
{
    GoCodeFormatter codeFormatter(tabSettings);

    codeFormatter.updateStateUntil(block);
    int indentation;
    int padding;
    codeFormatter.calcIndentation(block, &indentation, &padding);

    if (isElectricCharacter(typedChar)) {
        int defaultIndentation;
        int defaultPadding;
        codeFormatter.calcIndentation(block, &defaultIndentation, &defaultPadding, true);
    }

    tabSettings.indentLine(block, indentation + padding, padding);
}
int CMakeIndenter::indentFor(const QTextBlock &block, const TextEditor::TabSettings &tabSettings)
{
    QTextBlock previousBlock = block.previous();
    // find the next previous block that is non-empty (contains non-whitespace characters)
    while (previousBlock.isValid() && lineIsEmpty(previousBlock.text()))
        previousBlock = previousBlock.previous();
    if (!previousBlock.isValid())
        return 0;

    const QString previousLine = previousBlock.text();
    const QString currentLine = block.text();
    int indentation = tabSettings.indentationColumn(previousLine);

    if (lineStartsBlock(previousLine))
        indentation += tabSettings.m_indentSize;
    if (lineEndsBlock(currentLine))
        indentation = qMax(0, indentation - tabSettings.m_indentSize);

    // increase/decrease/keep the indentation level depending on if we have more opening or closing parantheses
    return qMax(0, indentation + tabSettings.m_indentSize * paranthesesLevel(previousLine));
}