diff options
author | Ivan Donchevskii <ivan.donchevskii@qt.io> | 2018-11-13 07:29:21 +0100 |
---|---|---|
committer | Ivan Donchevskii <ivan.donchevskii@qt.io> | 2018-11-14 09:29:41 +0000 |
commit | e9d0083ccd80c1edd09fb1dd5e97d48585b5507f (patch) | |
tree | 0697412c83d17b189db9dd2b70aa376b238c10b7 | |
parent | 9a85ce88a7254d9d54c42930a5514f0dd6308ce0 (diff) | |
download | qt-creator-e9d0083ccd80c1edd09fb1dd5e97d48585b5507f.tar.gz |
ClangFormat: Do not format text but indent only
Provide the separate infrastructure for the formatting
but use it only when QTC_FORMAT_INSTEAD_OF_INDENT is
provided in run environment.
Fixes: QTCREATORBUG-21447
Fixes: QTCREATORBUG-21459
Change-Id: I1ad6fe23f5de17016c0c7b18749c6977fc03a22b
Reviewed-by: Marco Bubke <marco.bubke@qt.io>
Reviewed-by: Nikolai Kosjar <nikolai.kosjar@qt.io>
-rw-r--r-- | src/plugins/clangformat/clangformatindenter.cpp | 103 | ||||
-rw-r--r-- | src/plugins/clangformat/clangformatindenter.h | 3 | ||||
-rw-r--r-- | src/plugins/texteditor/indenter.cpp | 7 | ||||
-rw-r--r-- | src/plugins/texteditor/indenter.h | 5 | ||||
-rw-r--r-- | src/plugins/texteditor/textdocument.cpp | 5 | ||||
-rw-r--r-- | src/plugins/texteditor/textdocument.h | 1 | ||||
-rw-r--r-- | src/plugins/texteditor/texteditor.cpp | 12 |
7 files changed, 88 insertions, 48 deletions
diff --git a/src/plugins/clangformat/clangformatindenter.cpp b/src/plugins/clangformat/clangformatindenter.cpp index 0d93059152..718d452635 100644 --- a/src/plugins/clangformat/clangformatindenter.cpp +++ b/src/plugins/clangformat/clangformatindenter.cpp @@ -65,18 +65,20 @@ void adjustFormatStyleForLineBreak(format::FormatStyle &style) style.KeepLineBreaksForNonEmptyLines = true; #endif style.MaxEmptyLinesToKeep = 2; + style.SortIncludes = false; + style.SortUsingDeclarations = false; } Replacements filteredReplacements(const Replacements &replacements, int offset, - int lengthForFilter, - int extraOffsetToAdd) + int extraOffsetToAdd, + bool onlyIndention) { Replacements filtered; for (const Replacement &replacement : replacements) { int replacementOffset = static_cast<int>(replacement.getOffset()); - if (replacementOffset >= offset + lengthForFilter) - break; + if (onlyIndention && replacementOffset != offset - 1) + continue; if (replacementOffset + 1 >= offset) replacementOffset += extraOffsetToAdd; @@ -138,7 +140,7 @@ void modifyToIndentEmptyLines(QByteArray &buffer, int &offset, int &length, cons { const QString blockText = block.text().trimmed(); const bool closingParenBlock = blockText.startsWith(')'); - if (length != 0 && !closingParenBlock) + if (!blockText.isEmpty() && !closingParenBlock) return; //This extra text works for the most cases. @@ -207,8 +209,8 @@ Replacements replacements(const Utils::FileName &fileName, return filteredReplacements(replacements, utf8Offset, - utf8Length, - extraOffset); + extraOffset, + block); } Utils::LineColumn utf16LineColumn(const QTextBlock &block, @@ -216,17 +218,14 @@ Utils::LineColumn utf16LineColumn(const QTextBlock &block, const QByteArray &utf8Buffer, int utf8Offset) { - // Do not search if the offset is less - we are not interested. - if (utf8Offset < blockOffsetUtf8 - 1) - return Utils::LineColumn(); - // If lastIndexOf('\n') returns -1 then we are fine to add 1 and get 0 offset. const int lineStartUtf8Offset = utf8Buffer.lastIndexOf('\n', utf8Offset - 1) + 1; - int line = block.blockNumber() + 1; // Init with the line corresponding the block. - if (utf8Offset == blockOffsetUtf8 - 1) { - // Our offset is the end of the previous line - --line; + + if (utf8Offset < blockOffsetUtf8) { + line -= static_cast<int>(std::count(utf8Buffer.begin() + lineStartUtf8Offset, + utf8Buffer.begin() + blockOffsetUtf8, + '\n')); } else { line += static_cast<int>(std::count(utf8Buffer.begin() + blockOffsetUtf8, utf8Buffer.begin() + lineStartUtf8Offset, @@ -333,41 +332,53 @@ void ClangFormatIndenter::indent(QTextDocument *doc, const QTextCursor &cursor, const QChar &typedChar, const TabSettings &tabSettings, - bool autoTriggered) + bool /*autoTriggered*/) { - if (typedChar == QChar::Null && (cursor.hasSelection() || !autoTriggered)) { - TextEditorWidget *editor = TextEditorWidget::currentTextEditorWidget(); - if (!editor) - return; - const Utils::FileName fileName = editor->textDocument()->filePath(); - int utf8Offset; - int utf8Length; - const QByteArray buffer = doc->toPlainText().toUtf8(); - if (cursor.hasSelection()) { - const QTextBlock start = doc->findBlock(cursor.selectionStart()); - const QTextBlock end = doc->findBlock(cursor.selectionEnd()); - utf8Offset = Utils::Text::utf8NthLineOffset(doc, buffer, start.blockNumber() + 1); - QTC_ASSERT(utf8Offset >= 0, return;); - utf8Length = selectedLines(doc, start, end).toUtf8().size(); - applyReplacements(start, - utf8Offset, - buffer, - replacements(fileName, buffer, utf8Offset, utf8Length)); - } else { - const QTextBlock block = cursor.block(); - utf8Offset = Utils::Text::utf8NthLineOffset(doc, buffer, block.blockNumber() + 1); - QTC_ASSERT(utf8Offset >= 0, return;); - utf8Length = block.text().toUtf8().size(); - applyReplacements(block, - utf8Offset, - buffer, - replacements(fileName, buffer, utf8Offset, utf8Length)); + if (cursor.hasSelection()) { + QTextBlock currentBlock = doc->findBlock(cursor.selectionStart()); + while (currentBlock.isValid() && currentBlock.position() < cursor.selectionEnd()) { + indentBlock(doc, currentBlock, typedChar, tabSettings); + currentBlock = currentBlock.next(); } } else { indentBlock(doc, cursor.block(), typedChar, tabSettings); } } +void ClangFormatIndenter::format(QTextDocument *doc, + const QTextCursor &cursor, + const TextEditor::TabSettings &/*tabSettings*/) +{ + TextEditorWidget *editor = TextEditorWidget::currentTextEditorWidget(); + if (!editor) + return; + + const Utils::FileName fileName = editor->textDocument()->filePath(); + int utf8Offset; + int utf8Length; + const QByteArray buffer = doc->toPlainText().toUtf8(); + if (cursor.hasSelection()) { + const QTextBlock start = doc->findBlock(cursor.selectionStart()); + const QTextBlock end = doc->findBlock(cursor.selectionEnd()); + utf8Offset = Utils::Text::utf8NthLineOffset(doc, buffer, start.blockNumber() + 1); + QTC_ASSERT(utf8Offset >= 0, return;); + utf8Length = selectedLines(doc, start, end).toUtf8().size(); + applyReplacements(start, + utf8Offset, + buffer, + replacements(fileName, buffer, utf8Offset, utf8Length)); + } else { + const QTextBlock block = cursor.block(); + utf8Offset = Utils::Text::utf8NthLineOffset(doc, buffer, block.blockNumber() + 1); + QTC_ASSERT(utf8Offset >= 0, return;); + utf8Length = block.text().toUtf8().size(); + applyReplacements(block, + utf8Offset, + buffer, + replacements(fileName, buffer, utf8Offset, utf8Length)); + } +} + void ClangFormatIndenter::reindent(QTextDocument *doc, const QTextCursor &cursor, const TabSettings &tabSettings) @@ -391,12 +402,11 @@ void ClangFormatIndenter::indentBlock(QTextDocument *doc, const QByteArray buffer = doc->toPlainText().toUtf8(); const int utf8Offset = Utils::Text::utf8NthLineOffset(doc, buffer, block.blockNumber() + 1); QTC_ASSERT(utf8Offset >= 0, return;); - const int utf8Length = block.text().toUtf8().size(); applyReplacements(block, utf8Offset, buffer, - replacements(fileName, buffer, utf8Offset, utf8Length, &block, typedChar)); + replacements(fileName, buffer, utf8Offset, 0, &block, typedChar)); } int ClangFormatIndenter::indentFor(const QTextBlock &block, const TextEditor::TabSettings &) @@ -411,9 +421,8 @@ int ClangFormatIndenter::indentFor(const QTextBlock &block, const TextEditor::Ta const QByteArray buffer = doc->toPlainText().toUtf8(); const int utf8Offset = Utils::Text::utf8NthLineOffset(doc, buffer, block.blockNumber() + 1); QTC_ASSERT(utf8Offset >= 0, return 0;); - const int utf8Length = block.text().toUtf8().size(); - Replacements toReplace = replacements(fileName, buffer, utf8Offset, utf8Length, &block); + Replacements toReplace = replacements(fileName, buffer, utf8Offset, 0, &block); if (toReplace.empty()) return -1; diff --git a/src/plugins/clangformat/clangformatindenter.h b/src/plugins/clangformat/clangformatindenter.h index dfe3b5b95f..cdd9ea24eb 100644 --- a/src/plugins/clangformat/clangformatindenter.h +++ b/src/plugins/clangformat/clangformatindenter.h @@ -40,6 +40,9 @@ public: void reindent(QTextDocument *doc, const QTextCursor &cursor, const TextEditor::TabSettings &tabSettings) override; + void format(QTextDocument *doc, + const QTextCursor &cursor, + const TextEditor::TabSettings &tabSettings) override; void indentBlock(QTextDocument *doc, const QTextBlock &block, const QChar &typedChar, diff --git a/src/plugins/texteditor/indenter.cpp b/src/plugins/texteditor/indenter.cpp index e5d939d29e..4e47a15abd 100644 --- a/src/plugins/texteditor/indenter.cpp +++ b/src/plugins/texteditor/indenter.cpp @@ -104,6 +104,13 @@ void Indenter::reindent(QTextDocument *doc, const QTextCursor &cursor, const Tab } } +void Indenter::format(QTextDocument *doc, + const QTextCursor &cursor, + const TabSettings &tabSettings) +{ + indent(doc, cursor, QChar::Null, tabSettings); +} + void Indenter::setCodeStylePreferences(ICodeStylePreferences *) { diff --git a/src/plugins/texteditor/indenter.h b/src/plugins/texteditor/indenter.h index 5b5cdb6a55..05a65c7243 100644 --- a/src/plugins/texteditor/indenter.h +++ b/src/plugins/texteditor/indenter.h @@ -67,6 +67,11 @@ public: const TabSettings &tabSettings, bool autoTriggered = true); + // By default just calls indent with default settings. + virtual void format(QTextDocument *doc, + const QTextCursor &cursor, + const TabSettings &tabSettings); + // Reindent at cursor. Selection will be adjusted according to the indentation // change of the first block. virtual void reindent(QTextDocument *doc, const QTextCursor &cursor, const TabSettings &tabSettings); diff --git a/src/plugins/texteditor/textdocument.cpp b/src/plugins/texteditor/textdocument.cpp index 6bc47e3f56..7363988c60 100644 --- a/src/plugins/texteditor/textdocument.cpp +++ b/src/plugins/texteditor/textdocument.cpp @@ -426,6 +426,11 @@ void TextDocument::autoReindent(const QTextCursor &cursor) d->m_indenter->reindent(&d->m_document, cursor, tabSettings()); } +void TextDocument::autoFormat(const QTextCursor &cursor) +{ + d->m_indenter->format(&d->m_document, cursor, tabSettings()); +} + QTextCursor TextDocument::indent(const QTextCursor &cursor, bool blockSelection, int column, int *offset) { diff --git a/src/plugins/texteditor/textdocument.h b/src/plugins/texteditor/textdocument.h index e05d202ead..67d4eae0f9 100644 --- a/src/plugins/texteditor/textdocument.h +++ b/src/plugins/texteditor/textdocument.h @@ -90,6 +90,7 @@ public: void autoIndent(const QTextCursor &cursor, QChar typedChar = QChar::Null, bool autoTriggered = true); void autoReindent(const QTextCursor &cursor); + void autoFormat(const QTextCursor &cursor); QTextCursor indent(const QTextCursor &cursor, bool blockSelection = false, int column = 0, int *offset = nullptr); QTextCursor unindent(const QTextCursor &cursor, bool blockSelection = false, int column = 0, diff --git a/src/plugins/texteditor/texteditor.cpp b/src/plugins/texteditor/texteditor.cpp index 37a57412bf..3ae7a79751 100644 --- a/src/plugins/texteditor/texteditor.cpp +++ b/src/plugins/texteditor/texteditor.cpp @@ -7132,11 +7132,21 @@ void TextEditorWidget::setIfdefedOutBlocks(const QList<BlockRange> &blocks) documentLayout->requestUpdate(); } +static bool applyFormattingInsteadOfIndentation() +{ + constexpr const char option[] = "QTC_FORMAT_INSTEAD_OF_INDENT"; + return qEnvironmentVariableIsSet(option); +} + void TextEditorWidget::format() { + static bool formattingInsteadOfIndentation = applyFormattingInsteadOfIndentation(); QTextCursor cursor = textCursor(); cursor.beginEditBlock(); - d->m_document->autoIndent(cursor, QChar::Null, false); + if (formattingInsteadOfIndentation) + d->m_document->autoFormat(cursor); + else + d->m_document->autoIndent(cursor); cursor.endEditBlock(); } |