summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorIvan Donchevskii <ivan.donchevskii@qt.io>2019-01-16 09:37:54 +0100
committerIvan Donchevskii <ivan.donchevskii@qt.io>2019-01-22 09:52:15 +0000
commitd7058e1afedfe609ff6e81222bd2137922bf7de3 (patch)
tree62d16136c8336646b8ef0ad4d220b7e0e8331203 /src
parent8b5beeb952448540a3834333b694919563d81ee2 (diff)
downloadqt-creator-d7058e1afedfe609ff6e81222bd2137922bf7de3.tar.gz
ClangFormat: Refactor indenter to allow ClangFormat unit-tests
We do not build texteditor files in unit-tests so some tricks were required to make ClangFormatIndenter available. First simple unit-test proofs it builds and runs. Change-Id: I81d5ea099bd27fd1c1ed8b5b7877299dcc62a67f Reviewed-by: Nikolai Kosjar <nikolai.kosjar@qt.io>
Diffstat (limited to 'src')
-rw-r--r--src/plugins/android/javaeditor.cpp2
-rw-r--r--src/plugins/android/javaindenter.cpp11
-rw-r--r--src/plugins/android/javaindenter.h9
-rw-r--r--src/plugins/clangformat/clangformat-source.pri8
-rw-r--r--src/plugins/clangformat/clangformat.pro6
-rw-r--r--src/plugins/clangformat/clangformat.qbs2
-rw-r--r--src/plugins/clangformat/clangformatbaseindenter.cpp500
-rw-r--r--src/plugins/clangformat/clangformatbaseindenter.h75
-rw-r--r--src/plugins/clangformat/clangformatindenter.cpp469
-rw-r--r--src/plugins/clangformat/clangformatindenter.h33
-rw-r--r--src/plugins/clangformat/clangformatplugin.cpp4
-rw-r--r--src/plugins/clangtools/clangfixitsrefactoringchanges.cpp10
-rw-r--r--src/plugins/clangtools/clangfixitsrefactoringchanges.h9
-rw-r--r--src/plugins/cmakeprojectmanager/cmakeeditor.cpp2
-rw-r--r--src/plugins/cmakeprojectmanager/cmakeindenter.cpp7
-rw-r--r--src/plugins/cmakeprojectmanager/cmakeindenter.h8
-rw-r--r--src/plugins/cppeditor/cppeditor.cpp3
-rw-r--r--src/plugins/cppeditor/cppeditordocument.cpp7
-rw-r--r--src/plugins/cpptools/cppcodestylepreferencesfactory.cpp4
-rw-r--r--src/plugins/cpptools/cppcodestylepreferencesfactory.h2
-rw-r--r--src/plugins/cpptools/cppcodestylesettingspage.cpp2
-rw-r--r--src/plugins/cpptools/cppmodelmanager.cpp1
-rw-r--r--src/plugins/cpptools/cppmodelmanager.h1
-rw-r--r--src/plugins/cpptools/cppqtstyleindenter.cpp43
-rw-r--r--src/plugins/cpptools/cppqtstyleindenter.h27
-rw-r--r--src/plugins/cpptools/cpprefactoringchanges.cpp9
-rw-r--r--src/plugins/fakevim/fakevimplugin.cpp2
-rw-r--r--src/plugins/glsleditor/glsleditor.cpp2
-rw-r--r--src/plugins/glsleditor/glslindenter.cpp50
-rw-r--r--src/plugins/glsleditor/glslindenter.h18
-rw-r--r--src/plugins/nim/editor/nimeditorfactory.cpp6
-rw-r--r--src/plugins/nim/editor/nimindenter.cpp7
-rw-r--r--src/plugins/nim/editor/nimindenter.h21
-rw-r--r--src/plugins/nim/settings/nimcodestylepreferencesfactory.cpp4
-rw-r--r--src/plugins/nim/settings/nimcodestylepreferencesfactory.h2
-rw-r--r--src/plugins/nim/settings/nimcodestylepreferenceswidget.cpp3
-rw-r--r--src/plugins/projectexplorer/jsonwizard/jsonwizardgeneratorfactory.cpp19
-rw-r--r--src/plugins/projectexplorer/projectfilewizardextension.cpp15
-rw-r--r--src/plugins/pythoneditor/pythoneditor.cpp2
-rw-r--r--src/plugins/pythoneditor/pythonindenter.cpp4
-rw-r--r--src/plugins/pythoneditor/pythonindenter.h6
-rw-r--r--src/plugins/qmldesigner/designercore/model/basetexteditmodifier.cpp4
-rw-r--r--src/plugins/qmljseditor/qmljseditor.cpp2
-rw-r--r--src/plugins/qmljseditor/qmljseditordocument.cpp2
-rw-r--r--src/plugins/qmljseditor/quicktoolbar.cpp4
-rw-r--r--src/plugins/qmljstools/qmljscodestylepreferencesfactory.cpp4
-rw-r--r--src/plugins/qmljstools/qmljscodestylepreferencesfactory.h2
-rw-r--r--src/plugins/qmljstools/qmljscodestylesettingspage.cpp3
-rw-r--r--src/plugins/qmljstools/qmljsindenter.cpp24
-rw-r--r--src/plugins/qmljstools/qmljsindenter.h15
-rw-r--r--src/plugins/qmljstools/qmljsrefactoringchanges.cpp4
-rw-r--r--src/plugins/texteditor/codestyleeditor.cpp7
-rw-r--r--src/plugins/texteditor/icodestylepreferencesfactory.h5
-rw-r--r--src/plugins/texteditor/indenter.h84
-rw-r--r--src/plugins/texteditor/normalindenter.cpp4
-rw-r--r--src/plugins/texteditor/normalindenter.h6
-rw-r--r--src/plugins/texteditor/plaintexteditorfactory.cpp2
-rw-r--r--src/plugins/texteditor/textdocument.cpp16
-rw-r--r--src/plugins/texteditor/textdocument.h5
-rw-r--r--src/plugins/texteditor/texteditor.cpp2
-rw-r--r--src/plugins/texteditor/texteditor.h4
-rw-r--r--src/plugins/texteditor/texteditor.pro7
-rw-r--r--src/plugins/texteditor/texteditor.qbs3
-rw-r--r--src/plugins/texteditor/textindenter.cpp (renamed from src/plugins/texteditor/indenter.cpp)85
-rw-r--r--src/plugins/texteditor/textindenter.h63
-rw-r--r--src/shared/clang/clang_installation.pri14
66 files changed, 978 insertions, 808 deletions
diff --git a/src/plugins/android/javaeditor.cpp b/src/plugins/android/javaeditor.cpp
index 8b023b1703..85ea22442b 100644
--- a/src/plugins/android/javaeditor.cpp
+++ b/src/plugins/android/javaeditor.cpp
@@ -49,7 +49,7 @@ static TextEditor::TextDocument *createJavaDocument()
auto doc = new TextEditor::TextDocument;
doc->setId(Constants::JAVA_EDITOR_ID);
doc->setMimeType(QLatin1String(Constants::JAVA_MIMETYPE));
- doc->setIndenter(new JavaIndenter);
+ doc->setIndenter(new JavaIndenter(doc->document()));
return doc;
}
diff --git a/src/plugins/android/javaindenter.cpp b/src/plugins/android/javaindenter.cpp
index 6b6d45d7ce..270e9cf988 100644
--- a/src/plugins/android/javaindenter.cpp
+++ b/src/plugins/android/javaindenter.cpp
@@ -31,7 +31,9 @@
using namespace Android;
using namespace Android::Internal;
-JavaIndenter::JavaIndenter() = default;
+JavaIndenter::JavaIndenter(QTextDocument *doc)
+ : TextEditor::TextIndenter(doc)
+{}
JavaIndenter::~JavaIndenter() = default;
@@ -44,20 +46,17 @@ bool JavaIndenter::isElectricCharacter(const QChar &ch) const
return false;
}
-void JavaIndenter::indentBlock(QTextDocument *doc,
- const QTextBlock &block,
+void JavaIndenter::indentBlock(const QTextBlock &block,
const QChar &typedChar,
const TextEditor::TabSettings &tabSettings)
{
- Q_UNUSED(doc);
int indent = indentFor(block, tabSettings);
if (typedChar == QLatin1Char('}'))
indent -= tabSettings.m_indentSize;
tabSettings.indentLine(block, qMax(0, indent));
}
-int JavaIndenter::indentFor(const QTextBlock &block,
- const TextEditor::TabSettings &tabSettings)
+int JavaIndenter::indentFor(const QTextBlock &block, const TextEditor::TabSettings &tabSettings)
{
QTextBlock previous = block.previous();
if (!previous.isValid())
diff --git a/src/plugins/android/javaindenter.h b/src/plugins/android/javaindenter.h
index 2b40851fd4..8a93058e83 100644
--- a/src/plugins/android/javaindenter.h
+++ b/src/plugins/android/javaindenter.h
@@ -25,20 +25,19 @@
#pragma once
-#include <texteditor/indenter.h>
+#include <texteditor/textindenter.h>
namespace Android {
namespace Internal {
-class JavaIndenter : public TextEditor::Indenter
+class JavaIndenter : public TextEditor::TextIndenter
{
public:
- JavaIndenter();
+ explicit JavaIndenter(QTextDocument *doc);
~JavaIndenter() override;
bool isElectricCharacter(const QChar &ch) const override;
- void indentBlock(QTextDocument *doc,
- const QTextBlock &block,
+ void indentBlock(const QTextBlock &block,
const QChar &typedChar,
const TextEditor::TabSettings &tabSettings) override;
diff --git a/src/plugins/clangformat/clangformat-source.pri b/src/plugins/clangformat/clangformat-source.pri
new file mode 100644
index 0000000000..4aafbe77bf
--- /dev/null
+++ b/src/plugins/clangformat/clangformat-source.pri
@@ -0,0 +1,8 @@
+INCLUDEPATH += $$PWD
+
+HEADERS += \
+ $$PWD/clangformatconstants.h \
+ $$PWD/clangformatbaseindenter.h
+
+SOURCES += \
+ $$PWD/clangformatbaseindenter.cpp
diff --git a/src/plugins/clangformat/clangformat.pro b/src/plugins/clangformat/clangformat.pro
index 6696b3b0de..2e168fdbc5 100644
--- a/src/plugins/clangformat/clangformat.pro
+++ b/src/plugins/clangformat/clangformat.pro
@@ -1,4 +1,5 @@
include(../../qtcreatorplugin.pri)
+include(clangformat-source.pri)
include(../../shared/clang/clang_installation.pri)
include(../../shared/clang/clang_defines.pri)
@@ -19,17 +20,16 @@ QMAKE_CXXFLAGS *= $$LLVM_CXXFLAGS
gcc:QMAKE_CXXFLAGS *= -Wno-comment
unix:!macos:QMAKE_LFLAGS += -Wl,--exclude-libs,ALL
-SOURCES = \
+SOURCES += \
clangformatconfigwidget.cpp \
clangformatindenter.cpp \
clangformatplugin.cpp \
clangformatutils.cpp
-HEADERS = \
+HEADERS += \
clangformatconfigwidget.h \
clangformatindenter.h \
clangformatplugin.h \
- clangformatconstants.h \
clangformatutils.h
FORMS += \
diff --git a/src/plugins/clangformat/clangformat.qbs b/src/plugins/clangformat/clangformat.qbs
index 6c23ee0430..cbfaffe657 100644
--- a/src/plugins/clangformat/clangformat.qbs
+++ b/src/plugins/clangformat/clangformat.qbs
@@ -30,6 +30,8 @@ QtcPlugin {
cpp.rpaths: base.concat(libclang.llvmLibDir)
files: [
+ "clangformatbaseindenter.h",
+ "clangformatbaseindenter.cpp",
"clangformatconfigwidget.cpp",
"clangformatconfigwidget.h",
"clangformatconfigwidget.ui",
diff --git a/src/plugins/clangformat/clangformatbaseindenter.cpp b/src/plugins/clangformat/clangformatbaseindenter.cpp
new file mode 100644
index 0000000000..dde629cdd0
--- /dev/null
+++ b/src/plugins/clangformat/clangformatbaseindenter.cpp
@@ -0,0 +1,500 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt Creator.
+**
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+****************************************************************************/
+
+#pragma once
+
+#include "clangformatbaseindenter.h"
+
+#include <clang/Tooling/Core/Replacement.h>
+
+#include <utils/fileutils.h>
+#include <utils/textutils.h>
+#include <utils/qtcassert.h>
+
+#include <QTextDocument>
+
+namespace ClangFormat {
+
+static void adjustFormatStyleForLineBreak(clang::format::FormatStyle &style)
+{
+ style.DisableFormat = false;
+ style.ColumnLimit = 0;
+#ifdef KEEP_LINE_BREAKS_FOR_NON_EMPTY_LINES_BACKPORTED
+ style.KeepLineBreaksForNonEmptyLines = true;
+#endif
+ style.MaxEmptyLinesToKeep = 2;
+ style.SortIncludes = false;
+ style.SortUsingDeclarations = false;
+}
+
+static llvm::StringRef clearExtraNewline(llvm::StringRef text)
+{
+ while (text.startswith("\n\n"))
+ text = text.drop_front();
+ return text;
+}
+
+static clang::tooling::Replacements filteredReplacements(
+ const clang::tooling::Replacements &replacements,
+ int offset,
+ int extraOffsetToAdd,
+ bool onlyIndention)
+{
+ clang::tooling::Replacements filtered;
+ for (const clang::tooling::Replacement &replacement : replacements) {
+ int replacementOffset = static_cast<int>(replacement.getOffset());
+ if (onlyIndention && replacementOffset != offset - 1)
+ continue;
+
+ if (replacementOffset + 1 >= offset)
+ replacementOffset += extraOffsetToAdd;
+
+ llvm::StringRef text = onlyIndention ? clearExtraNewline(replacement.getReplacementText())
+ : replacement.getReplacementText();
+
+ llvm::Error error = filtered.add(
+ clang::tooling::Replacement(replacement.getFilePath(),
+ static_cast<unsigned int>(replacementOffset),
+ replacement.getLength(),
+ text));
+ // Throws if error is not checked.
+ if (error)
+ break;
+ }
+ return filtered;
+}
+
+static void trimFirstNonEmptyBlock(const QTextBlock &currentBlock)
+{
+ QTextBlock prevBlock = currentBlock.previous();
+ while (prevBlock.position() > 0 && prevBlock.text().trimmed().isEmpty())
+ prevBlock = prevBlock.previous();
+
+ if (prevBlock.text().trimmed().isEmpty())
+ return;
+
+ const QString initialText = prevBlock.text();
+ if (!initialText.at(initialText.size() - 1).isSpace())
+ return;
+
+ auto lastNonSpace = std::find_if_not(initialText.rbegin(),
+ initialText.rend(),
+ [](const QChar &letter) { return letter.isSpace(); });
+ const int extraSpaceCount = static_cast<int>(std::distance(initialText.rbegin(), lastNonSpace));
+
+ QTextCursor cursor(prevBlock);
+ cursor.beginEditBlock();
+ cursor.movePosition(QTextCursor::Right,
+ QTextCursor::MoveAnchor,
+ initialText.size() - extraSpaceCount);
+ cursor.movePosition(QTextCursor::Right, QTextCursor::KeepAnchor, extraSpaceCount);
+ cursor.removeSelectedText();
+ cursor.endEditBlock();
+}
+
+static void trimCurrentBlock(const QTextBlock &currentBlock)
+{
+ if (currentBlock.text().trimmed().isEmpty()) {
+ // Clear the block containing only spaces
+ QTextCursor cursor(currentBlock);
+ cursor.beginEditBlock();
+ cursor.movePosition(QTextCursor::EndOfBlock, QTextCursor::KeepAnchor);
+ cursor.removeSelectedText();
+ cursor.endEditBlock();
+ }
+}
+
+// Returns the total langth of previous lines with pure whitespace.
+static int previousEmptyLinesLength(const QTextBlock &currentBlock)
+{
+ int length{0};
+ QTextBlock prevBlock = currentBlock.previous();
+ while (prevBlock.position() > 0 && prevBlock.text().trimmed().isEmpty()) {
+ length += prevBlock.text().length() + 1;
+ prevBlock = prevBlock.previous();
+ }
+
+ return length;
+}
+
+static void modifyToIndentEmptyLines(
+ QByteArray &buffer, int offset, int &length, const QTextBlock &block, bool secondTry)
+{
+ const QString blockText = block.text().trimmed();
+ const bool closingParenBlock = blockText.startsWith(')');
+ if (blockText.isEmpty() || closingParenBlock) {
+ //This extra text works for the most cases.
+ QByteArray dummyText("a;");
+
+ // Search for previous character
+ QTextBlock prevBlock = block.previous();
+ bool prevBlockIsEmpty = prevBlock.position() > 0 && prevBlock.text().trimmed().isEmpty();
+ while (prevBlockIsEmpty) {
+ prevBlock = prevBlock.previous();
+ prevBlockIsEmpty = prevBlock.position() > 0 && prevBlock.text().trimmed().isEmpty();
+ }
+ if (prevBlock.text().endsWith(','))
+ dummyText = "int a";
+
+ if (closingParenBlock) {
+ if (prevBlock.text().endsWith(','))
+ dummyText = "int a";
+ else
+ dummyText = "&& a";
+ }
+
+ length += dummyText.length();
+ buffer.insert(offset, dummyText);
+ }
+
+ if (secondTry) {
+ int nextLinePos = buffer.indexOf('\n', offset);
+ if (nextLinePos > 0) {
+ // If first try was not successful try to put ')' in the end of the line to close possibly
+ // unclosed parentheses.
+ // TODO: Does it help to add different endings depending on the context?
+ buffer.insert(nextLinePos, ')');
+ length += 1;
+ }
+ }
+}
+
+static const int kMaxLinesFromCurrentBlock = 200;
+
+static Utils::LineColumn utf16LineColumn(const QTextBlock &block,
+ int blockOffsetUtf8,
+ const QByteArray &utf8Buffer,
+ int utf8Offset)
+{
+ // 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) {
+ 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,
+ '\n'));
+ }
+
+ const QByteArray lineText = utf8Buffer.mid(lineStartUtf8Offset,
+ utf8Offset - lineStartUtf8Offset);
+ return Utils::LineColumn(line, QString::fromUtf8(lineText).size() + 1);
+}
+
+static TextEditor::Replacements utf16Replacements(const QTextBlock &block,
+ int blockOffsetUtf8,
+ const QByteArray &utf8Buffer,
+ const clang::tooling::Replacements &replacements)
+{
+ TextEditor::Replacements convertedReplacements;
+ convertedReplacements.reserve(replacements.size());
+ for (const clang::tooling::Replacement &replacement : replacements) {
+ const Utils::LineColumn lineColUtf16 = utf16LineColumn(block,
+ blockOffsetUtf8,
+ utf8Buffer,
+ static_cast<int>(
+ replacement.getOffset()));
+ if (!lineColUtf16.isValid())
+ continue;
+ const int utf16Offset = Utils::Text::positionInText(block.document(),
+ lineColUtf16.line,
+ lineColUtf16.column);
+ const int utf16Length = QString::fromUtf8(
+ utf8Buffer.mid(static_cast<int>(replacement.getOffset()),
+ static_cast<int>(replacement.getLength())))
+ .size();
+ convertedReplacements.emplace_back(utf16Offset,
+ utf16Length,
+ QString::fromStdString(replacement.getReplacementText()));
+ }
+
+ return convertedReplacements;
+}
+
+static void applyReplacements(const QTextBlock &block, const TextEditor::Replacements &replacements)
+{
+ if (replacements.empty())
+ return;
+
+ int fullOffsetShift = 0;
+ QTextCursor editCursor(block);
+ for (const TextEditor::Replacement &replacement : replacements) {
+ editCursor.beginEditBlock();
+ editCursor.setPosition(replacement.offset + fullOffsetShift);
+ editCursor.movePosition(QTextCursor::NextCharacter,
+ QTextCursor::KeepAnchor,
+ replacement.length);
+ editCursor.removeSelectedText();
+ editCursor.insertText(replacement.text);
+ editCursor.endEditBlock();
+ fullOffsetShift += replacement.text.length() - replacement.length;
+ }
+}
+
+static QString selectedLines(QTextDocument *doc,
+ const QTextBlock &startBlock,
+ const QTextBlock &endBlock)
+{
+ QString text = Utils::Text::textAt(QTextCursor(doc),
+ startBlock.position(),
+ std::max(0,
+ endBlock.position() + endBlock.length()
+ - startBlock.position() - 1));
+ while (!text.isEmpty() && text.rbegin()->isSpace())
+ text.chop(1);
+ return text;
+}
+
+ClangFormatBaseIndenter::ClangFormatBaseIndenter(QTextDocument *doc)
+ : TextEditor::Indenter(doc)
+{}
+
+TextEditor::IndentationForBlock ClangFormatBaseIndenter::indentationForBlocks(
+ const QVector<QTextBlock> &blocks, const TextEditor::TabSettings & /*tabSettings*/)
+{
+ TextEditor::IndentationForBlock ret;
+ for (QTextBlock block : blocks)
+ ret.insert(block.blockNumber(), indentFor(block));
+ return ret;
+}
+
+void ClangFormatBaseIndenter::indent(const QTextCursor &cursor, const QChar &typedChar)
+{
+ if (cursor.hasSelection()) {
+ // Calling currentBlock.next() might be unsafe because we change the document.
+ // Let's operate with block numbers instead.
+ const int startNumber = m_doc->findBlock(cursor.selectionStart()).blockNumber();
+ const int endNumber = m_doc->findBlock(cursor.selectionEnd()).blockNumber();
+ for (int currentBlockNumber = startNumber; currentBlockNumber <= endNumber;
+ ++currentBlockNumber) {
+ const QTextBlock currentBlock = m_doc->findBlockByNumber(currentBlockNumber);
+ if (currentBlock.isValid()) {
+ const int blocksAmount = m_doc->blockCount();
+ indentBlock(currentBlock, typedChar);
+ QTC_CHECK(blocksAmount == m_doc->blockCount()
+ && "ClangFormat plugin indentation changed the amount of blocks.");
+ }
+ }
+ } else {
+ indentBlock(cursor.block(), typedChar);
+ }
+}
+
+void ClangFormatBaseIndenter::indent(const QTextCursor &cursor,
+ const QChar &typedChar,
+ const TextEditor::TabSettings & /*tabSettings*/)
+{
+ indent(cursor, typedChar);
+}
+
+void ClangFormatBaseIndenter::reindent(const QTextCursor &cursor,
+ const TextEditor::TabSettings & /*tabSettings*/)
+{
+ indent(cursor, QChar::Null);
+}
+
+TextEditor::Replacements ClangFormatBaseIndenter::format(
+ const QTextCursor &cursor, const TextEditor::TabSettings & /*tabSettings*/)
+{
+ int utf8Offset;
+ int utf8Length;
+ const QByteArray buffer = m_doc->toPlainText().toUtf8();
+ QTextBlock block = cursor.block();
+ if (cursor.hasSelection()) {
+ block = m_doc->findBlock(cursor.selectionStart());
+ const QTextBlock end = m_doc->findBlock(cursor.selectionEnd());
+ utf8Offset = Utils::Text::utf8NthLineOffset(m_doc, buffer, block.blockNumber() + 1);
+ QTC_ASSERT(utf8Offset >= 0, return TextEditor::Replacements(););
+ utf8Length = selectedLines(m_doc, block, end).toUtf8().size();
+
+ } else {
+ const QTextBlock block = cursor.block();
+ utf8Offset = Utils::Text::utf8NthLineOffset(m_doc, buffer, block.blockNumber() + 1);
+ QTC_ASSERT(utf8Offset >= 0, return TextEditor::Replacements(););
+ utf8Length = block.text().toUtf8().size();
+ }
+
+ const TextEditor::Replacements toReplace
+ = replacements(buffer, utf8Offset, utf8Length, block, QChar::Null, false);
+ applyReplacements(block, toReplace);
+
+ return toReplace;
+}
+
+void ClangFormatBaseIndenter::indentBlock(const QTextBlock &block, const QChar &typedChar)
+{
+ trimFirstNonEmptyBlock(block);
+ trimCurrentBlock(block);
+ const QByteArray buffer = m_doc->toPlainText().toUtf8();
+ const int utf8Offset = Utils::Text::utf8NthLineOffset(m_doc, buffer, block.blockNumber() + 1);
+ QTC_ASSERT(utf8Offset >= 0, return;);
+
+ applyReplacements(block, replacements(buffer, utf8Offset, 0, block, typedChar));
+}
+
+void ClangFormatBaseIndenter::indentBlock(const QTextBlock &block,
+ const QChar &typedChar,
+ const TextEditor::TabSettings & /*tabSettings*/)
+{
+ indentBlock(block, typedChar);
+}
+
+int ClangFormatBaseIndenter::indentFor(const QTextBlock &block)
+{
+ trimFirstNonEmptyBlock(block);
+ trimCurrentBlock(block);
+ const QByteArray buffer = m_doc->toPlainText().toUtf8();
+ const int utf8Offset = Utils::Text::utf8NthLineOffset(m_doc, buffer, block.blockNumber() + 1);
+ QTC_ASSERT(utf8Offset >= 0, return 0;);
+
+ const TextEditor::Replacements toReplace = replacements(buffer, utf8Offset, 0, block);
+
+ if (toReplace.empty())
+ return -1;
+
+ const TextEditor::Replacement &replacement = toReplace.front();
+ int afterLineBreak = replacement.text.lastIndexOf('\n');
+ afterLineBreak = (afterLineBreak < 0) ? 0 : afterLineBreak + 1;
+ return static_cast<int>(replacement.text.size() - afterLineBreak);
+}
+
+int ClangFormatBaseIndenter::indentFor(const QTextBlock &block,
+ const TextEditor::TabSettings & /*tabSettings*/)
+{
+ return indentFor(block);
+}
+
+bool ClangFormatBaseIndenter::isElectricCharacter(const QChar &ch) const
+{
+ switch (ch.toLatin1()) {
+ case '{':
+ case '}':
+ case ':':
+ case '#':
+ case '<':
+ case '>':
+ case ';':
+ case '(':
+ case ')':
+ case ',':
+ case '.':
+ return true;
+ }
+ return false;
+}
+
+clang::format::FormatStyle ClangFormatBaseIndenter::styleForFile() const
+{
+ llvm::Expected<clang::format::FormatStyle> style
+ = clang::format::getStyle("file", m_fileName.toString().toStdString(), "none");
+ if (style)
+ return *style;
+
+ handleAllErrors(style.takeError(), [](const llvm::ErrorInfoBase &) {
+ // do nothing
+ });
+
+ return clang::format::getLLVMStyle();
+}
+
+TextEditor::Replacements ClangFormatBaseIndenter::replacements(QByteArray buffer,
+ int utf8Offset,
+ int utf8Length,
+ const QTextBlock &block,
+ const QChar &typedChar,
+ bool onlyIndention,
+ bool secondTry) const
+{
+ clang::format::FormatStyle style = styleForFile();
+
+ int originalOffsetUtf8 = utf8Offset;
+ int originalLengthUtf8 = utf8Length;
+ QByteArray originalBuffer = buffer;
+
+ int extraOffset = 0;
+ if (onlyIndention) {
+ if (block.blockNumber() > kMaxLinesFromCurrentBlock) {
+ extraOffset = Utils::Text::utf8NthLineOffset(block.document(),
+ buffer,
+ block.blockNumber()
+ - kMaxLinesFromCurrentBlock);
+ }
+ int endOffset = Utils::Text::utf8NthLineOffset(block.document(),
+ buffer,
+ block.blockNumber()
+ + kMaxLinesFromCurrentBlock);
+ if (endOffset == -1)
+ endOffset = buffer.size();
+
+ buffer = buffer.mid(extraOffset, endOffset - extraOffset);
+ utf8Offset -= extraOffset;
+
+ const int emptySpaceLength = previousEmptyLinesLength(block);
+ utf8Offset -= emptySpaceLength;
+ buffer.remove(utf8Offset, emptySpaceLength);
+
+ extraOffset += emptySpaceLength;
+
+ adjustFormatStyleForLineBreak(style);
+ if (typedChar == QChar::Null)
+ modifyToIndentEmptyLines(buffer, utf8Offset, utf8Length, block, secondTry);
+ }
+
+ std::vector<clang::tooling::Range> ranges{
+ {static_cast<unsigned int>(utf8Offset), static_cast<unsigned int>(utf8Length)}};
+ clang::format::FormattingAttemptStatus status;
+
+ clang::tooling::Replacements clangReplacements = reformat(style,
+ buffer.data(),
+ ranges,
+ m_fileName.toString().toStdString(),
+ &status);
+
+ if (!status.FormatComplete)
+ return TextEditor::Replacements();
+
+ const clang::tooling::Replacements filtered = filteredReplacements(clangReplacements,
+ utf8Offset,
+ extraOffset,
+ onlyIndention);
+ const bool canTryAgain = onlyIndention && typedChar == QChar::Null && !secondTry;
+ if (canTryAgain && filtered.empty()) {
+ return replacements(originalBuffer,
+ originalOffsetUtf8,
+ originalLengthUtf8,
+ block,
+ typedChar,
+ onlyIndention,
+ true);
+ }
+
+ return utf16Replacements(block, originalOffsetUtf8, originalBuffer, filtered);
+}
+
+} // namespace ClangFormat
diff --git a/src/plugins/clangformat/clangformatbaseindenter.h b/src/plugins/clangformat/clangformatbaseindenter.h
new file mode 100644
index 0000000000..47137420d7
--- /dev/null
+++ b/src/plugins/clangformat/clangformatbaseindenter.h
@@ -0,0 +1,75 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt Creator.
+**
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+****************************************************************************/
+
+#pragma once
+
+#include <texteditor/indenter.h>
+
+#include <clang/Format/Format.h>
+
+namespace ClangFormat {
+
+class ClangFormatBaseIndenter : public TextEditor::Indenter
+{
+public:
+ ClangFormatBaseIndenter(QTextDocument *doc);
+
+ TextEditor::IndentationForBlock indentationForBlocks(
+ const QVector<QTextBlock> &blocks, const TextEditor::TabSettings & /*tabSettings*/) override;
+ void indent(const QTextCursor &cursor,
+ const QChar &typedChar,
+ const TextEditor::TabSettings & /*tabSettings*/) override;
+
+ void reindent(const QTextCursor &cursor,
+ const TextEditor::TabSettings & /*tabSettings*/) override;
+
+ TextEditor::Replacements format(const QTextCursor &cursor,
+ const TextEditor::TabSettings & /*tabSettings*/) override;
+
+ void indentBlock(const QTextBlock &block,
+ const QChar &typedChar,
+ const TextEditor::TabSettings & /*tabSettings*/) override;
+
+ int indentFor(const QTextBlock &block, const TextEditor::TabSettings & /*tabSettings*/) override;
+
+ bool isElectricCharacter(const QChar &ch) const override;
+
+protected:
+ virtual clang::format::FormatStyle styleForFile() const;
+
+private:
+ void indent(const QTextCursor &cursor, const QChar &typedChar);
+ void indentBlock(const QTextBlock &block, const QChar &typedChar);
+ int indentFor(const QTextBlock &block);
+ TextEditor::Replacements replacements(QByteArray buffer,
+ int utf8Offset,
+ int utf8Length,
+ const QTextBlock &block,
+ const QChar &typedChar = QChar::Null,
+ bool onlyIndention = true,
+ bool secondTry = false) const;
+};
+
+} // namespace ClangFormat
diff --git a/src/plugins/clangformat/clangformatindenter.cpp b/src/plugins/clangformat/clangformatindenter.cpp
index e5d14392e4..b52b4e9ce6 100644
--- a/src/plugins/clangformat/clangformatindenter.cpp
+++ b/src/plugins/clangformat/clangformatindenter.cpp
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2018 The Qt Company Ltd.
+** Copyright (C) 2019 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of Qt Creator.
@@ -24,479 +24,26 @@
****************************************************************************/
#include "clangformatindenter.h"
-
#include "clangformatutils.h"
-#include <clang/Format/Format.h>
-#include <clang/Tooling/Core/Replacement.h>
-
-#include <cpptools/cppmodelmanager.h>
-#include <texteditor/textdocument.h>
-#include <texteditor/texteditor.h>
-
-#include <utils/hostosinfo.h>
-#include <utils/textutils.h>
-#include <utils/qtcassert.h>
-
-#include <llvm/Config/llvm-config.h>
-
-#include <QDir>
-#include <QFileInfo>
-#include <QTextBlock>
-
-#include <fstream>
-
-using ClangReplacement = clang::tooling::Replacement;
-using ClangReplacements = clang::tooling::Replacements;
-using QtReplacement = TextEditor::Replacement;
-using QtReplacements = TextEditor::Replacements;
+#include <texteditor/tabsettings.h>
using namespace clang;
using namespace format;
-using namespace llvm;
-using namespace tooling;
-using namespace ProjectExplorer;
using namespace TextEditor;
namespace ClangFormat {
-namespace {
-
-void adjustFormatStyleForLineBreak(format::FormatStyle &style)
-{
- style.DisableFormat = false;
- style.ColumnLimit = 0;
-#ifdef KEEP_LINE_BREAKS_FOR_NON_EMPTY_LINES_BACKPORTED
- style.KeepLineBreaksForNonEmptyLines = true;
-#endif
- style.MaxEmptyLinesToKeep = 2;
- style.SortIncludes = false;
- style.SortUsingDeclarations = false;
-}
-
-StringRef clearExtraNewline(StringRef text)
-{
- while (text.startswith("\n\n"))
- text = text.drop_front();
- return text;
-}
-
-ClangReplacements filteredReplacements(const ClangReplacements &replacements,
- int offset,
- int extraOffsetToAdd,
- bool onlyIndention)
-{
- ClangReplacements filtered;
- for (const ClangReplacement &replacement : replacements) {
- int replacementOffset = static_cast<int>(replacement.getOffset());
- if (onlyIndention && replacementOffset != offset - 1)
- continue;
-
- if (replacementOffset + 1 >= offset)
- replacementOffset += extraOffsetToAdd;
-
- StringRef text = onlyIndention ? clearExtraNewline(replacement.getReplacementText())
- : replacement.getReplacementText();
-
- Error error = filtered.add(ClangReplacement(replacement.getFilePath(),
- static_cast<unsigned int>(replacementOffset),
- replacement.getLength(),
- text));
- // Throws if error is not checked.
- if (error)
- break;
- }
- return filtered;
-}
-
-void trimFirstNonEmptyBlock(const QTextBlock &currentBlock)
-{
- QTextBlock prevBlock = currentBlock.previous();
- while (prevBlock.position() > 0 && prevBlock.text().trimmed().isEmpty())
- prevBlock = prevBlock.previous();
-
- if (prevBlock.text().trimmed().isEmpty())
- return;
-
- const QString initialText = prevBlock.text();
- if (!initialText.at(initialText.size() - 1).isSpace())
- return;
-
- auto lastNonSpace = std::find_if_not(initialText.rbegin(),
- initialText.rend(),
- [](const QChar &letter) {
- return letter.isSpace();
- });
- const int extraSpaceCount = static_cast<int>(std::distance(initialText.rbegin(), lastNonSpace));
-
- QTextCursor cursor(prevBlock);
- cursor.beginEditBlock();
- cursor.movePosition(QTextCursor::Right, QTextCursor::MoveAnchor,
- initialText.size() - extraSpaceCount);
- cursor.movePosition(QTextCursor::Right, QTextCursor::KeepAnchor, extraSpaceCount);
- cursor.removeSelectedText();
- cursor.endEditBlock();
-}
-
-void trimCurrentBlock(const QTextBlock &currentBlock)
-{
- if (currentBlock.text().trimmed().isEmpty()) {
- // Clear the block containing only spaces
- QTextCursor cursor(currentBlock);
- cursor.beginEditBlock();
- cursor.movePosition(QTextCursor::EndOfBlock, QTextCursor::KeepAnchor);
- cursor.removeSelectedText();
- cursor.endEditBlock();
- }
-}
-
-// Returns the total langth of previous lines with pure whitespace.
-int previousEmptyLinesLength(const QTextBlock &currentBlock)
-{
- int length{0};
- QTextBlock prevBlock = currentBlock.previous();
- while (prevBlock.position() > 0 && prevBlock.text().trimmed().isEmpty()) {
- length += prevBlock.text().length() + 1;
- prevBlock = prevBlock.previous();
- }
-
- return length;
-}
-
-void modifyToIndentEmptyLines(
- QByteArray &buffer, int offset, int &length, const QTextBlock &block, bool secondTry)
-{
- const QString blockText = block.text().trimmed();
- const bool closingParenBlock = blockText.startsWith(')');
- if (blockText.isEmpty() || closingParenBlock) {
- //This extra text works for the most cases.
- QByteArray dummyText("a;");
-
- // Search for previous character
- QTextBlock prevBlock = block.previous();
- bool prevBlockIsEmpty = prevBlock.position() > 0 && prevBlock.text().trimmed().isEmpty();
- while (prevBlockIsEmpty) {
- prevBlock = prevBlock.previous();
- prevBlockIsEmpty = prevBlock.position() > 0 && prevBlock.text().trimmed().isEmpty();
- }
- if (prevBlock.text().endsWith(','))
- dummyText = "int a";
-
- if (closingParenBlock) {
- if (prevBlock.text().endsWith(','))
- dummyText = "int a";
- else
- dummyText = "&& a";
- }
-
- length += dummyText.length();
- buffer.insert(offset, dummyText);
- }
+ClangFormatIndenter::ClangFormatIndenter(QTextDocument *doc)
+ : ClangFormatBaseIndenter(doc)
+{}
- if (secondTry) {
- int nextLinePos = buffer.indexOf('\n', offset);
- if (nextLinePos > 0) {
- // If first try was not successful try to put ')' in the end of the line to close possibly
- // unclosed parentheses.
- // TODO: Does it help to add different endings depending on the context?
- buffer.insert(nextLinePos, ')');
- length += 1;
- }
- }
-}
-
-static const int kMaxLinesFromCurrentBlock = 200;
-
-Utils::LineColumn utf16LineColumn(const QTextBlock &block,
- int blockOffsetUtf8,
- const QByteArray &utf8Buffer,
- int utf8Offset)
-{
- // 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) {
- 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,
- '\n'));
- }
-
- const QByteArray lineText = utf8Buffer.mid(lineStartUtf8Offset,
- utf8Offset - lineStartUtf8Offset);
- return Utils::LineColumn(line, QString::fromUtf8(lineText).size() + 1);
-}
-
-QtReplacements utf16Replacements(const QTextBlock &block,
- int blockOffsetUtf8,
- const QByteArray &utf8Buffer,
- const ClangReplacements &replacements)
+FormatStyle ClangFormatIndenter::styleForFile() const
{
- QtReplacements convertedReplacements;
- convertedReplacements.reserve(replacements.size());
- for (const ClangReplacement &replacement : replacements) {
- const Utils::LineColumn lineColUtf16 = utf16LineColumn(block,
- blockOffsetUtf8,
- utf8Buffer,
- static_cast<int>(
- replacement.getOffset()));
- if (!lineColUtf16.isValid())
- continue;
- const int utf16Offset = Utils::Text::positionInText(block.document(),
- lineColUtf16.line,
- lineColUtf16.column);
- const int utf16Length = QString::fromUtf8(
- utf8Buffer.mid(static_cast<int>(replacement.getOffset()),
- static_cast<int>(replacement.getLength())))
- .size();
- convertedReplacements.emplace_back(utf16Offset,
- utf16Length,
- QString::fromStdString(replacement.getReplacementText()));
- }
-
- return convertedReplacements;
-}
-
-QtReplacements replacements(const Utils::FileName &fileName,
- QByteArray buffer,
- int utf8Offset,
- int utf8Length,
- const QTextBlock &block,
- const QChar &typedChar = QChar::Null,
- bool onlyIndention = true,
- bool secondTry = false)
-{
- FormatStyle style = styleForFile(fileName);
-
- int originalOffsetUtf8 = utf8Offset;
- int originalLengthUtf8 = utf8Length;
- QByteArray originalBuffer = buffer;
-
- int extraOffset = 0;
- if (onlyIndention) {
- if (block.blockNumber() > kMaxLinesFromCurrentBlock) {
- extraOffset = Utils::Text::utf8NthLineOffset(
- block.document(), buffer, block.blockNumber() - kMaxLinesFromCurrentBlock);
- }
- int endOffset = Utils::Text::utf8NthLineOffset(
- block.document(), buffer, block.blockNumber() + kMaxLinesFromCurrentBlock);
- if (endOffset == -1)
- endOffset = buffer.size();
-
- buffer = buffer.mid(extraOffset, endOffset - extraOffset);
- utf8Offset -= extraOffset;
-
- const int emptySpaceLength = previousEmptyLinesLength(block);
- utf8Offset -= emptySpaceLength;
- buffer.remove(utf8Offset, emptySpaceLength);
-
- extraOffset += emptySpaceLength;
-
- adjustFormatStyleForLineBreak(style);
- if (typedChar == QChar::Null)
- modifyToIndentEmptyLines(buffer, utf8Offset, utf8Length, block, secondTry);
- }
-
- std::vector<Range> ranges{{static_cast<unsigned int>(utf8Offset),
- static_cast<unsigned int>(utf8Length)}};
- FormattingAttemptStatus status;
-
- ClangReplacements clangReplacements = reformat(style,
- buffer.data(),
- ranges,
- fileName.toString().toStdString(),
- &status);
-
- if (!status.FormatComplete)
- QtReplacements();
-
- const ClangReplacements filtered = filteredReplacements(clangReplacements,
- utf8Offset,
- extraOffset,
- onlyIndention);
-
- const bool canTryAgain = onlyIndention && typedChar == QChar::Null && !secondTry;
- if (canTryAgain && filtered.empty()) {
- return replacements(fileName,
- originalBuffer,
- originalOffsetUtf8,
- originalLengthUtf8,
- block,
- typedChar,
- onlyIndention,
- true);
- }
-
- return utf16Replacements(block, originalOffsetUtf8, originalBuffer, filtered);
-}
-
-void applyReplacements(const QTextBlock &block, const QtReplacements &replacements)
-{
- if (replacements.empty())
- return;
-
- int fullOffsetShift = 0;
- QTextCursor editCursor(block);
- for (const QtReplacement &replacement : replacements) {
- editCursor.beginEditBlock();
- editCursor.setPosition(replacement.offset + fullOffsetShift);
- editCursor.movePosition(QTextCursor::NextCharacter,
- QTextCursor::KeepAnchor,
- replacement.length);
- editCursor.removeSelectedText();
- editCursor.insertText(replacement.text);
- editCursor.endEditBlock();
- fullOffsetShift += replacement.text.length() - replacement.length;
- }
-}
-
-QString selectedLines(QTextDocument *doc, const QTextBlock &startBlock, const QTextBlock &endBlock)
-{
- QString text = Utils::Text::textAt(
- QTextCursor(doc),
- startBlock.position(),
- std::max(0, endBlock.position() + endBlock.length() - startBlock.position() - 1));
- while (!text.isEmpty() && text.rbegin()->isSpace())
- text.chop(1);
- return text;
-}
-
-} // anonymous namespace
-
-bool ClangFormatIndenter::isElectricCharacter(const QChar &ch) const
-{
- switch (ch.toLatin1()) {
- case '{':
- case '}':
- case ':':
- case '#':
- case '<':
- case '>':
- case ';':
- case '(':
- case ')':
- case ',':
- case '.':
- return true;
- }
- return false;
-}
-
-void ClangFormatIndenter::indent(QTextDocument *doc,
- const QTextCursor &cursor,
- const QChar &typedChar,
- const TabSettings &tabSettings,
- bool /*autoTriggered*/)
-{
- if (cursor.hasSelection()) {
- // Calling currentBlock.next() might be unsafe because we change the document.
- // Let's operate with block numbers instead.
- const int startNumber = doc->findBlock(cursor.selectionStart()).blockNumber();
- const int endNumber = doc->findBlock(cursor.selectionEnd()).blockNumber();
- for (int currentBlockNumber = startNumber; currentBlockNumber <= endNumber;
- ++currentBlockNumber) {
- const QTextBlock currentBlock = doc->findBlockByNumber(currentBlockNumber);
- if (currentBlock.isValid()) {
- const int blocksAmount = doc->blockCount();
- indentBlock(doc, currentBlock, typedChar, tabSettings);
- QTC_CHECK(blocksAmount == doc->blockCount()
- && "ClangFormat plugin indentation changed the amount of blocks.");
- }
- }
- } else {
- indentBlock(doc, cursor.block(), typedChar, tabSettings);
- }
-}
-
-QtReplacements ClangFormatIndenter::format(QTextDocument *doc,
- const Utils::FileName &fileName,
- const QTextCursor &cursor,
- const TextEditor::TabSettings & /*tabSettings*/)
-{
- int utf8Offset;
- int utf8Length;
- const QByteArray buffer = doc->toPlainText().toUtf8();
- QTextBlock block = cursor.block();
- if (cursor.hasSelection()) {
- block = doc->findBlock(cursor.selectionStart());
- const QTextBlock end = doc->findBlock(cursor.selectionEnd());
- utf8Offset = Utils::Text::utf8NthLineOffset(doc, buffer, block.blockNumber() + 1);
- QTC_ASSERT(utf8Offset >= 0, return QtReplacements(););
- utf8Length = selectedLines(doc, block, end).toUtf8().size();
-
- } else {
- const QTextBlock block = cursor.block();
- utf8Offset = Utils::Text::utf8NthLineOffset(doc, buffer, block.blockNumber() + 1);
- QTC_ASSERT(utf8Offset >= 0, return QtReplacements(););
- utf8Length = block.text().toUtf8().size();
- }
-
- const QtReplacements toReplace
- = replacements(fileName, buffer, utf8Offset, utf8Length, block, QChar::Null, false);
- applyReplacements(block, toReplace);
-
- return toReplace;
-}
-
-void ClangFormatIndenter::reindent(QTextDocument *doc,
- const QTextCursor &cursor,
- const TabSettings &tabSettings)
-{
- indent(doc, cursor, QChar::Null, tabSettings);
-}
-
-void ClangFormatIndenter::indentBlock(QTextDocument *doc,
- const QTextBlock &block,
- const QChar &typedChar,
- const TabSettings &tabSettings)
-{
- Q_UNUSED(tabSettings);
-
- TextEditorWidget *editor = TextEditorWidget::currentTextEditorWidget();
- if (!editor)
- return;
-
- const Utils::FileName fileName = editor->textDocument()->filePath();
- trimFirstNonEmptyBlock(block);
- trimCurrentBlock(block);
- const QByteArray buffer = doc->toPlainText().toUtf8();
- const int utf8Offset = Utils::Text::utf8NthLineOffset(doc, buffer, block.blockNumber() + 1);
- QTC_ASSERT(utf8Offset >= 0, return;);
-
- applyReplacements(block,
- replacements(fileName, buffer, utf8Offset, 0, block, typedChar));
-}
-
-int ClangFormatIndenter::indentFor(const QTextBlock &block, const TextEditor::TabSettings &)
-{
- TextEditorWidget *editor = TextEditorWidget::currentTextEditorWidget();
- if (!editor)
- return -1;
-
- const Utils::FileName fileName = editor->textDocument()->filePath();
- trimFirstNonEmptyBlock(block);
- trimCurrentBlock(block);
- const QTextDocument *doc = block.document();
- const QByteArray buffer = doc->toPlainText().toUtf8();
- const int utf8Offset = Utils::Text::utf8NthLineOffset(doc, buffer, block.blockNumber() + 1);
- QTC_ASSERT(utf8Offset >= 0, return 0;);
-
- const QtReplacements toReplace = replacements(fileName, buffer, utf8Offset, 0, block);
-
- if (toReplace.empty())
- return -1;
-
- const QtReplacement &replacement = toReplace.front();
- int afterLineBreak = replacement.text.lastIndexOf('\n');
- afterLineBreak = (afterLineBreak < 0) ? 0 : afterLineBreak + 1;
- return static_cast<int>(replacement.text.size() - afterLineBreak);
+ return ClangFormat::styleForFile(m_fileName);
}
-TabSettings ClangFormatIndenter::tabSettings() const
+Utils::optional<TabSettings> ClangFormatIndenter::tabSettings() const
{
FormatStyle style = currentProjectStyle();
TabSettings tabSettings;
diff --git a/src/plugins/clangformat/clangformatindenter.h b/src/plugins/clangformat/clangformatindenter.h
index a12ffaee44..5631e32db1 100644
--- a/src/plugins/clangformat/clangformatindenter.h
+++ b/src/plugins/clangformat/clangformatindenter.h
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2018 The Qt Company Ltd.
+** Copyright (C) 2019 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of Qt Creator.
@@ -25,35 +25,20 @@
#pragma once
-#include <texteditor/indenter.h>
+#include "clangformatbaseindenter.h"
+
+#include <texteditor/tabsettings.h>
namespace ClangFormat {
-class ClangFormatIndenter final : public TextEditor::Indenter
+class ClangFormatIndenter final : public ClangFormatBaseIndenter
{
public:
- void indent(QTextDocument *doc,
- const QTextCursor &cursor,
- const QChar &typedChar,
- const TextEditor::TabSettings &tabSettings,
- bool autoTriggered = true) override;
- void reindent(QTextDocument *doc,
- const QTextCursor &cursor,
- const TextEditor::TabSettings &tabSettings) override;
- TextEditor::Replacements format(QTextDocument *doc,
- const Utils::FileName &fileName,
- const QTextCursor &cursor,
- const TextEditor::TabSettings &tabSettings) override;
- void indentBlock(QTextDocument *doc,
- const QTextBlock &block,
- const QChar &typedChar,
- const TextEditor::TabSettings &tabSettings) override;
- int indentFor(const QTextBlock &block, const TextEditor::TabSettings &tabSettings) override;
-
- bool isElectricCharacter(const QChar &ch) const override;
+ ClangFormatIndenter(QTextDocument *doc);
+ Utils::optional<TextEditor::TabSettings> tabSettings() const override;
- bool hasTabSettings() const override { return true; }
- TextEditor::TabSettings tabSettings() const override;
+private:
+ clang::format::FormatStyle styleForFile() const override;
};
} // namespace ClangFormat
diff --git a/src/plugins/clangformat/clangformatplugin.cpp b/src/plugins/clangformat/clangformatplugin.cpp
index d5882aab58..2d848d9501 100644
--- a/src/plugins/clangformat/clangformatplugin.cpp
+++ b/src/plugins/clangformat/clangformatplugin.cpp
@@ -84,9 +84,9 @@ public:
return nullptr;
}
- TextEditor::Indenter *createIndenter() const override
+ TextEditor::Indenter *createIndenter(QTextDocument *doc) const override
{
- return new ClangFormatIndenter();
+ return new ClangFormatIndenter(doc);
}
};
diff --git a/src/plugins/clangtools/clangfixitsrefactoringchanges.cpp b/src/plugins/clangtools/clangfixitsrefactoringchanges.cpp
index feff3a8e2c..88b17fb42a 100644
--- a/src/plugins/clangtools/clangfixitsrefactoringchanges.cpp
+++ b/src/plugins/clangtools/clangfixitsrefactoringchanges.cpp
@@ -32,6 +32,7 @@
#include <texteditor/icodestylepreferencesfactory.h>
#include <texteditor/indenter.h>
+#include <texteditor/tabsettings.h>
#include <texteditor/texteditorsettings.h>
#include <QDebug>
@@ -83,7 +84,6 @@ bool FixitsRefactoringFile::apply()
ICodeStylePreferencesFactory *factory = TextEditorSettings::codeStyleFactory(
CppTools::Constants::CPP_SETTINGS_ID);
- std::unique_ptr<TextEditor::Indenter> indenter(factory->createIndenter());
const TextEditor::TabSettings tabSettings
= CppTools::CppCodeStyleSettings::currentProjectTabSettings();
@@ -103,6 +103,9 @@ bool FixitsRefactoringFile::apply()
// Apply
QTextDocument *doc = document(op.fileName);
+ std::unique_ptr<TextEditor::Indenter> indenter(factory->createIndenter(doc));
+ indenter->setFileName(Utils::FileName::fromString(op.fileName));
+
QTextCursor cursor(doc);
cursor.setPosition(op.pos);
cursor.setPosition(op.pos + op.length, QTextCursor::KeepAnchor);
@@ -139,10 +142,7 @@ void FixitsRefactoringFile::tryToFormat(TextEditor::Indenter &indenter,
cursor.movePosition(QTextCursor::Right,
QTextCursor::KeepAnchor,
op.text.length());
- const Replacements replacements = indenter.format(doc,
- Utils::FileName::fromString(op.fileName),
- cursor,
- tabSettings);
+ const Replacements replacements = indenter.format(cursor, tabSettings);
cursor.endEditBlock();
if (replacements.empty())
diff --git a/src/plugins/clangtools/clangfixitsrefactoringchanges.h b/src/plugins/clangtools/clangfixitsrefactoringchanges.h
index 63aea839b1..c1fcf38c09 100644
--- a/src/plugins/clangtools/clangfixitsrefactoringchanges.h
+++ b/src/plugins/clangtools/clangfixitsrefactoringchanges.h
@@ -25,6 +25,8 @@
#pragma once
+#include <texteditor/indenter.h>
+
#include <utils/changeset.h>
#include <utils/textfileformat.h>
@@ -32,13 +34,6 @@
#include <QTextDocument>
#include <QVector>
-namespace TextEditor {
-class Indenter;
-class Replacement;
-using Replacements = std::vector<Replacement>;
-class TabSettings;
-}
-
namespace ClangTools {
namespace Internal {
diff --git a/src/plugins/cmakeprojectmanager/cmakeeditor.cpp b/src/plugins/cmakeprojectmanager/cmakeeditor.cpp
index 122569616e..c5c0fe5b74 100644
--- a/src/plugins/cmakeprojectmanager/cmakeeditor.cpp
+++ b/src/plugins/cmakeprojectmanager/cmakeeditor.cpp
@@ -229,7 +229,7 @@ CMakeEditorFactory::CMakeEditorFactory()
setEditorCreator([]() { return new CMakeEditor; });
setEditorWidgetCreator([]() { return new CMakeEditorWidget; });
setDocumentCreator(createCMakeDocument);
- setIndenterCreator([]() { return new CMakeIndenter; });
+ setIndenterCreator([](QTextDocument *doc) { return new CMakeIndenter(doc); });
setUseGenericHighlighter(true);
setCommentDefinition(Utils::CommentDefinition::HashStyle);
setCodeFoldingSupported(true);
diff --git a/src/plugins/cmakeprojectmanager/cmakeindenter.cpp b/src/plugins/cmakeprojectmanager/cmakeindenter.cpp
index 882f0277a6..3ba47a634d 100644
--- a/src/plugins/cmakeprojectmanager/cmakeindenter.cpp
+++ b/src/plugins/cmakeprojectmanager/cmakeindenter.cpp
@@ -34,6 +34,10 @@
namespace CMakeProjectManager {
namespace Internal {
+CMakeIndenter::CMakeIndenter(QTextDocument *doc)
+ : TextEditor::TextIndenter(doc)
+{}
+
bool CMakeIndenter::isElectricCharacter(const QChar &ch) const
{
return ch == QLatin1Char('(') || ch == QLatin1Char(')');
@@ -98,7 +102,8 @@ static int paranthesesLevel(const QString &line)
return -1;
}
-int CMakeIndenter::indentFor(const QTextBlock &block, const TextEditor::TabSettings &tabSettings)
+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)
diff --git a/src/plugins/cmakeprojectmanager/cmakeindenter.h b/src/plugins/cmakeprojectmanager/cmakeindenter.h
index a47bdcced5..f7d80b0e0b 100644
--- a/src/plugins/cmakeprojectmanager/cmakeindenter.h
+++ b/src/plugins/cmakeprojectmanager/cmakeindenter.h
@@ -27,17 +27,19 @@
#include "cmake_global.h"
-#include <texteditor/indenter.h>
+#include <texteditor/textindenter.h>
namespace CMakeProjectManager {
namespace Internal {
-class CMAKE_EXPORT CMakeIndenter : public TextEditor::Indenter
+class CMAKE_EXPORT CMakeIndenter : public TextEditor::TextIndenter
{
public:
+ explicit CMakeIndenter(QTextDocument *doc);
bool isElectricCharacter(const QChar &ch) const override;
- int indentFor(const QTextBlock &block, const TextEditor::TabSettings &tabSettings) override;
+ int indentFor(const QTextBlock &block,
+ const TextEditor::TabSettings &tabSettings) override;
};
} // namespace Internal
diff --git a/src/plugins/cppeditor/cppeditor.cpp b/src/plugins/cppeditor/cppeditor.cpp
index a2b622a2f9..e7064d3165 100644
--- a/src/plugins/cppeditor/cppeditor.cpp
+++ b/src/plugins/cppeditor/cppeditor.cpp
@@ -42,7 +42,8 @@ CppEditor::CppEditor()
void CppEditor::decorateEditor(TextEditor::TextEditorWidget *editor)
{
editor->textDocument()->setSyntaxHighlighter(new CppHighlighter);
- editor->textDocument()->setIndenter(new CppTools::CppQtStyleIndenter);
+ editor->textDocument()->setIndenter(
+ new CppTools::CppQtStyleIndenter(editor->textDocument()->document()));
editor->setAutoCompleter(new CppAutoCompleter);
}
diff --git a/src/plugins/cppeditor/cppeditordocument.cpp b/src/plugins/cppeditor/cppeditordocument.cpp
index 68e3e6547e..c8951c12eb 100644
--- a/src/plugins/cppeditor/cppeditordocument.cpp
+++ b/src/plugins/cppeditor/cppeditordocument.cpp
@@ -111,7 +111,7 @@ CppEditorDocument::CppEditorDocument()
ICodeStylePreferencesFactory *factory
= TextEditorSettings::codeStyleFactory(CppTools::Constants::CPP_SETTINGS_ID);
- setIndenter(factory->createIndenter());
+ setIndenter(factory->createIndenter(document()));
connect(this, &TextEditor::TextDocument::tabSettingsChanged,
this, &CppEditorDocument::invalidateFormatterCache);
@@ -243,6 +243,7 @@ void CppEditorDocument::onFilePathChanged(const Utils::FileName &oldPath,
Q_UNUSED(oldPath);
if (!newPath.isEmpty()) {
+ indenter()->setFileName(newPath);
setMimeType(Utils::mimeTypeForFile(newPath.toFileInfo()).name());
connect(this, &Core::IDocument::contentsChanged,
@@ -443,9 +444,7 @@ CppTools::BaseEditorDocumentProcessor *CppEditorDocument::processor()
TextEditor::TabSettings CppEditorDocument::tabSettings() const
{
- return indenter()->hasTabSettings()
- ? indenter()->tabSettings()
- : TextEditor::TextDocument::tabSettings();
+ return indenter()->tabSettings().value_or(TextEditor::TextDocument::tabSettings());
}
} // namespace Internal
diff --git a/src/plugins/cpptools/cppcodestylepreferencesfactory.cpp b/src/plugins/cpptools/cppcodestylepreferencesfactory.cpp
index 00da046edc..4c0ca8d9a5 100644
--- a/src/plugins/cpptools/cppcodestylepreferencesfactory.cpp
+++ b/src/plugins/cpptools/cppcodestylepreferencesfactory.cpp
@@ -111,9 +111,9 @@ QWidget *CppCodeStylePreferencesFactory::createEditor(TextEditor::ICodeStylePref
return widget;
}
-TextEditor::Indenter *CppCodeStylePreferencesFactory::createIndenter() const
+TextEditor::Indenter *CppCodeStylePreferencesFactory::createIndenter(QTextDocument *doc) const
{
- return new CppQtStyleIndenter();
+ return new CppQtStyleIndenter(doc);
}
QString CppCodeStylePreferencesFactory::snippetProviderGroupId() const
diff --git a/src/plugins/cpptools/cppcodestylepreferencesfactory.h b/src/plugins/cpptools/cppcodestylepreferencesfactory.h
index 233022a31a..eefe3adce2 100644
--- a/src/plugins/cpptools/cppcodestylepreferencesfactory.h
+++ b/src/plugins/cpptools/cppcodestylepreferencesfactory.h
@@ -41,7 +41,7 @@ public:
TextEditor::ICodeStylePreferences *createCodeStyle() const override;
QWidget *createEditor(TextEditor::ICodeStylePreferences *settings,
QWidget *parent) const override;
- TextEditor::Indenter *createIndenter() const override;
+ TextEditor::Indenter *createIndenter(QTextDocument *doc) const override;
QString snippetProviderGroupId() const override;
QString previewText() const override;
};
diff --git a/src/plugins/cpptools/cppcodestylesettingspage.cpp b/src/plugins/cpptools/cppcodestylesettingspage.cpp
index c80537db9b..f803516358 100644
--- a/src/plugins/cpptools/cppcodestylesettingspage.cpp
+++ b/src/plugins/cpptools/cppcodestylesettingspage.cpp
@@ -481,7 +481,7 @@ void CppCodeStylePreferencesWidget::updatePreview()
QTextCursor tc = preview->textCursor();
tc.beginEditBlock();
while (block.isValid()) {
- preview->textDocument()->indenter()->indentBlock(doc, block, QChar::Null, ts);
+ preview->textDocument()->indenter()->indentBlock(block, QChar::Null, ts);
block = block.next();
}
diff --git a/src/plugins/cpptools/cppmodelmanager.cpp b/src/plugins/cpptools/cppmodelmanager.cpp
index 45ab82efec..f5c257b6d2 100644
--- a/src/plugins/cpptools/cppmodelmanager.cpp
+++ b/src/plugins/cpptools/cppmodelmanager.cpp
@@ -61,7 +61,6 @@
#include <projectexplorer/projectexplorer.h>
#include <projectexplorer/projectmacro.h>
#include <projectexplorer/session.h>
-#include <texteditor/indenter.h>
#include <utils/fileutils.h>
#include <utils/qtcassert.h>
diff --git a/src/plugins/cpptools/cppmodelmanager.h b/src/plugins/cpptools/cppmodelmanager.h
index 0eac5abf87..302e447ade 100644
--- a/src/plugins/cpptools/cppmodelmanager.h
+++ b/src/plugins/cpptools/cppmodelmanager.h
@@ -49,7 +49,6 @@ namespace CPlusPlus { class LookupContext; }
namespace ProjectExplorer { class Project; }
namespace TextEditor {
class BaseHoverHandler;
-class Indenter;
class TextDocument;
} // namespace TextEditor
diff --git a/src/plugins/cpptools/cppqtstyleindenter.cpp b/src/plugins/cpptools/cppqtstyleindenter.cpp
index 54cb3cc9ed..97ffd666e3 100644
--- a/src/plugins/cpptools/cppqtstyleindenter.cpp
+++ b/src/plugins/cpptools/cppqtstyleindenter.cpp
@@ -36,7 +36,8 @@
using namespace CppTools;
-CppQtStyleIndenter::CppQtStyleIndenter()
+CppQtStyleIndenter::CppQtStyleIndenter(QTextDocument *doc)
+ : TextEditor::TextIndenter(doc)
{
// Just for safety. setCodeStylePreferences should be called when the editor the
// indenter belongs to gets initialized.
@@ -67,13 +68,10 @@ static bool isElectricInLine(const QChar ch, const QString &text)
return text.contains(QLatin1String("break"));
case ':':
// switch cases and access declarations should be reindented
- if (text.contains(QLatin1String("case"))
- || text.contains(QLatin1String("default"))
- || text.contains(QLatin1String("public"))
- || text.contains(QLatin1String("private"))
- || text.contains(QLatin1String("protected"))
- || text.contains(QLatin1String("signals"))
- || text.contains(QLatin1String("Q_SIGNALS"))) {
+ if (text.contains(QLatin1String("case")) || text.contains(QLatin1String("default"))
+ || text.contains(QLatin1String("public")) || text.contains(QLatin1String("private"))
+ || text.contains(QLatin1String("protected")) || text.contains(QLatin1String("signals"))
+ || text.contains(QLatin1String("Q_SIGNALS"))) {
return true;
}
@@ -93,13 +91,10 @@ static bool isElectricInLine(const QChar ch, const QString &text)
return true;
}
-void CppQtStyleIndenter::indentBlock(QTextDocument *doc,
- const QTextBlock &block,
+void CppQtStyleIndenter::indentBlock(const QTextBlock &block,
const QChar &typedChar,
const TextEditor::TabSettings &tabSettings)
{
- Q_UNUSED(doc)
-
QtStyleCodeFormatter codeFormatter(tabSettings, codeStyleSettings());
codeFormatter.updateStateUntil(block);
@@ -124,15 +119,13 @@ void CppQtStyleIndenter::indentBlock(QTextDocument *doc,
tabSettings.indentLine(block, indent + padding, padding);
}
-void CppQtStyleIndenter::indent(QTextDocument *doc,
- const QTextCursor &cursor,
+void CppQtStyleIndenter::indent(const QTextCursor &cursor,
const QChar &typedChar,
- const TextEditor::TabSettings &tabSettings,
- bool /*autoTriggered*/)
+ const TextEditor::TabSettings &tabSettings)
{
if (cursor.hasSelection()) {
- QTextBlock block = doc->findBlock(cursor.selectionStart());
- const QTextBlock end = doc->findBlock(cursor.selectionEnd()).next();
+ QTextBlock block = m_doc->findBlock(cursor.selectionStart());
+ const QTextBlock end = m_doc->findBlock(cursor.selectionEnd()).next();
QtStyleCodeFormatter codeFormatter(tabSettings, codeStyleSettings());
codeFormatter.updateStateUntil(block);
@@ -149,7 +142,7 @@ void CppQtStyleIndenter::indent(QTextDocument *doc,
} while (block.isValid() && block != end);
tc.endEditBlock();
} else {
- indentBlock(doc, cursor.block(), typedChar, tabSettings);
+ indentBlock(cursor.block(), typedChar, tabSettings);
}
}
@@ -160,13 +153,14 @@ void CppQtStyleIndenter::setCodeStylePreferences(TextEditor::ICodeStylePreferenc
m_cppCodeStylePreferences = cppCodeStylePreferences;
}
-void CppQtStyleIndenter::invalidateCache(QTextDocument *doc)
+void CppQtStyleIndenter::invalidateCache()
{
QtStyleCodeFormatter formatter;
- formatter.invalidateCache(doc);
+ formatter.invalidateCache(m_doc);
}
-int CppQtStyleIndenter::indentFor(const QTextBlock &block, const TextEditor::TabSettings &tabSettings)
+int CppQtStyleIndenter::indentFor(const QTextBlock &block,
+ const TextEditor::TabSettings &tabSettings)
{
QtStyleCodeFormatter codeFormatter(tabSettings, codeStyleSettings());
@@ -185,9 +179,8 @@ CppCodeStyleSettings CppQtStyleIndenter::codeStyleSettings() const
return CppCodeStyleSettings();
}
-TextEditor::IndentationForBlock
-CppQtStyleIndenter::indentationForBlocks(const QVector<QTextBlock> &blocks,
- const TextEditor::TabSettings &tabSettings)
+TextEditor::IndentationForBlock CppQtStyleIndenter::indentationForBlocks(
+ const QVector<QTextBlock> &blocks, const TextEditor::TabSettings &tabSettings)
{
QtStyleCodeFormatter codeFormatter(tabSettings, codeStyleSettings());
diff --git a/src/plugins/cpptools/cppqtstyleindenter.h b/src/plugins/cpptools/cppqtstyleindenter.h
index 05a36c883e..3b8fb07168 100644
--- a/src/plugins/cpptools/cppqtstyleindenter.h
+++ b/src/plugins/cpptools/cppqtstyleindenter.h
@@ -27,10 +27,9 @@
#include "cpptools_global.h"
-#include <texteditor/indenter.h>
+#include <texteditor/textindenter.h>
-namespace TextEditor
-{
+namespace TextEditor {
class ICodeStylePreferences;
}
@@ -38,32 +37,30 @@ namespace CppTools {
class CppCodeStyleSettings;
class CppCodeStylePreferences;
-class CPPTOOLS_EXPORT CppQtStyleIndenter : public TextEditor::Indenter
+class CPPTOOLS_EXPORT CppQtStyleIndenter : public TextEditor::TextIndenter
{
public:
- CppQtStyleIndenter();
+ explicit CppQtStyleIndenter(QTextDocument *doc);
~CppQtStyleIndenter() override;
bool isElectricCharacter(const QChar &ch) const override;
- void indentBlock(QTextDocument *doc,
- const QTextBlock &block,
+ void indentBlock(const QTextBlock &block,
const QChar &typedChar,
const TextEditor::TabSettings &tabSettings) override;
- void indent(QTextDocument *doc,
- const QTextCursor &cursor,
+ void indent(const QTextCursor &cursor,
const QChar &typedChar,
- const TextEditor::TabSettings &tabSettings,
- bool autoTriggered = true) override;
+ const TextEditor::TabSettings &tabSettings) override;
void setCodeStylePreferences(TextEditor::ICodeStylePreferences *preferences) override;
- void invalidateCache(QTextDocument *doc) override;
+ void invalidateCache() override;
int indentFor(const QTextBlock &block, const TextEditor::TabSettings &tabSettings) override;
- TextEditor::IndentationForBlock indentationForBlocks(const QVector<QTextBlock> &blocks,
- const TextEditor::TabSettings &tabSettings) override;
+ TextEditor::IndentationForBlock indentationForBlocks(
+ const QVector<QTextBlock> &blocks, const TextEditor::TabSettings &tabSettings) override;
+
private:
CppCodeStyleSettings codeStyleSettings() const;
CppCodeStylePreferences *m_cppCodeStylePreferences = nullptr;
};
-} // CppTools
+} // namespace CppTools
diff --git a/src/plugins/cpptools/cpprefactoringchanges.cpp b/src/plugins/cpptools/cpprefactoringchanges.cpp
index 929a6ec020..138a5a3693 100644
--- a/src/plugins/cpptools/cpprefactoringchanges.cpp
+++ b/src/plugins/cpptools/cpprefactoringchanges.cpp
@@ -56,8 +56,8 @@ public:
const TextEditor::TabSettings &tabSettings =
ProjectExplorer::actualTabSettings(fileName, textDocument);
- CppQtStyleIndenter indenter;
- indenter.indent(selection.document(), selection, QChar::Null, tabSettings);
+ CppQtStyleIndenter indenter(selection.document());
+ indenter.indent(selection, QChar::Null, tabSettings);
}
void reindentSelection(const QTextCursor &selection,
@@ -67,8 +67,9 @@ public:
const TextEditor::TabSettings &tabSettings =
ProjectExplorer::actualTabSettings(fileName, textDocument);
- CppQtStyleIndenter indenter;
- indenter.reindent(selection.document(), selection, tabSettings);
+ CppQtStyleIndenter indenter(selection.document());
+ indenter.reindent(selection,
+ tabSettings);
}
void fileChanged(const QString &fileName) override
diff --git a/src/plugins/fakevim/fakevimplugin.cpp b/src/plugins/fakevim/fakevimplugin.cpp
index 537e47b18a..1807efb910 100644
--- a/src/plugins/fakevim/fakevimplugin.cpp
+++ b/src/plugins/fakevim/fakevimplugin.cpp
@@ -1633,7 +1633,7 @@ void FakeVimPluginPrivate::editorOpened(IEditor *editor)
while (!cursor.atBlockEnd())
cursor.deleteChar();
} else {
- tew->textDocument()->indenter()->indentBlock(doc, block, typedChar, tabSettings);
+ tew->textDocument()->indenter()->indentBlock(block, typedChar, tabSettings);
}
block = block.next();
}
diff --git a/src/plugins/glsleditor/glsleditor.cpp b/src/plugins/glsleditor/glsleditor.cpp
index 33a4dafa47..c018e15f90 100644
--- a/src/plugins/glsleditor/glsleditor.cpp
+++ b/src/plugins/glsleditor/glsleditor.cpp
@@ -319,7 +319,7 @@ GlslEditorFactory::GlslEditorFactory()
setDocumentCreator([]() { return new TextDocument(Constants::C_GLSLEDITOR_ID); });
setEditorWidgetCreator([]() { return new GlslEditorWidget; });
- setIndenterCreator([]() { return new GlslIndenter; });
+ setIndenterCreator([](QTextDocument *doc) { return new GlslIndenter(doc); });
setSyntaxHighlighterCreator([]() { return new GlslHighlighter; });
setCommentDefinition(Utils::CommentDefinition::CppStyle);
setCompletionAssistProvider(new GlslCompletionAssistProvider);
diff --git a/src/plugins/glsleditor/glslindenter.cpp b/src/plugins/glsleditor/glslindenter.cpp
index b2c533f1e2..87b12f98e9 100644
--- a/src/plugins/glsleditor/glslindenter.cpp
+++ b/src/plugins/glsleditor/glslindenter.cpp
@@ -38,26 +38,25 @@
namespace GlslEditor {
namespace Internal {
+GlslIndenter::GlslIndenter(QTextDocument *doc)
+ : TextEditor::TextIndenter(doc)
+{}
GlslIndenter::~GlslIndenter() = default;
bool GlslIndenter::isElectricCharacter(const QChar &ch) const
{
- return ch == QLatin1Char('{')
- || ch == QLatin1Char('}')
- || ch == QLatin1Char(':')
- || ch == QLatin1Char('#');
+ return ch == QLatin1Char('{') || ch == QLatin1Char('}') || ch == QLatin1Char(':')
+ || ch == QLatin1Char('#');
}
-void GlslIndenter::indentBlock(QTextDocument *doc,
- const QTextBlock &block,
+void GlslIndenter::indentBlock(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());
+ CppTools::QtStyleCodeFormatter
+ codeFormatter(tabSettings,
+ CppTools::CppToolsSettings::instance()->cppCodeStyle()->codeStyleSettings());
codeFormatter.updateStateUntil(block);
int indent;
@@ -77,19 +76,19 @@ void GlslIndenter::indentBlock(QTextDocument *doc,
tabSettings.indentLine(block, indent + padding, padding);
}
-void GlslIndenter::indent(QTextDocument *doc,
- const QTextCursor &cursor,
+void GlslIndenter::indent(const QTextCursor &cursor,
const QChar &typedChar,
- const TextEditor::TabSettings &tabSettings,
- bool /*autoTriggered*/)
+ const TextEditor::TabSettings &tabSettings)
{
if (cursor.hasSelection()) {
- QTextBlock block = doc->findBlock(cursor.selectionStart());
- const QTextBlock end = doc->findBlock(cursor.selectionEnd()).next();
+ QTextBlock block = m_doc->findBlock(cursor.selectionStart());
+ const QTextBlock end = m_doc->findBlock(cursor.selectionEnd()).next();
// TODO: do something with it
CppTools::QtStyleCodeFormatter codeFormatter(tabSettings,
- CppTools::CppToolsSettings::instance()->cppCodeStyle()->codeStyleSettings());
+ CppTools::CppToolsSettings::instance()
+ ->cppCodeStyle()
+ ->codeStyleSettings());
codeFormatter.updateStateUntil(block);
QTextCursor tc = cursor;
@@ -104,14 +103,15 @@ void GlslIndenter::indent(QTextDocument *doc,
} while (block.isValid() && block != end);
tc.endEditBlock();
} else {
- indentBlock(doc, cursor.block(), typedChar, tabSettings);
+ indentBlock(cursor.block(), typedChar, tabSettings);
}
}
int GlslIndenter::indentFor(const QTextBlock &block, const TextEditor::TabSettings &tabSettings)
{
- CppTools::QtStyleCodeFormatter codeFormatter(tabSettings,
- CppTools::CppToolsSettings::instance()->cppCodeStyle()->codeStyleSettings());
+ CppTools::QtStyleCodeFormatter
+ codeFormatter(tabSettings,
+ CppTools::CppToolsSettings::instance()->cppCodeStyle()->codeStyleSettings());
codeFormatter.updateStateUntil(block);
int indent;
@@ -121,12 +121,12 @@ int GlslIndenter::indentFor(const QTextBlock &block, const TextEditor::TabSettin
return indent;
}
-TextEditor::IndentationForBlock
-GlslIndenter::indentationForBlocks(const QVector<QTextBlock> &blocks,
- const TextEditor::TabSettings &tabSettings)
+TextEditor::IndentationForBlock GlslIndenter::indentationForBlocks(
+ const QVector<QTextBlock> &blocks, const TextEditor::TabSettings &tabSettings)
{
- CppTools::QtStyleCodeFormatter codeFormatter(tabSettings,
- CppTools::CppToolsSettings::instance()->cppCodeStyle()->codeStyleSettings());
+ CppTools::QtStyleCodeFormatter
+ codeFormatter(tabSettings,
+ CppTools::CppToolsSettings::instance()->cppCodeStyle()->codeStyleSettings());
codeFormatter.updateStateUntil(blocks.last());
diff --git a/src/plugins/glsleditor/glslindenter.h b/src/plugins/glsleditor/glslindenter.h
index 75495f8303..beb6aaa849 100644
--- a/src/plugins/glsleditor/glslindenter.h
+++ b/src/plugins/glsleditor/glslindenter.h
@@ -25,31 +25,29 @@
#pragma once
-#include <texteditor/indenter.h>
+#include <texteditor/textindenter.h>
namespace GlslEditor {
namespace Internal {
-class GlslIndenter : public TextEditor::Indenter
+class GlslIndenter : public TextEditor::TextIndenter
{
public:
+ explicit GlslIndenter(QTextDocument *doc);
~GlslIndenter() override;
bool isElectricCharacter(const QChar &ch) const override;
- void indentBlock(QTextDocument *doc,
- const QTextBlock &block,
+ void indentBlock(const QTextBlock &block,
const QChar &typedChar,
const TextEditor::TabSettings &tabSettings) override;
- void indent(QTextDocument *doc,
- const QTextCursor &cursor,
+ void indent(const QTextCursor &cursor,
const QChar &typedChar,
- const TextEditor::TabSettings &tabSettings,
- bool autoTriggered = true) override;
+ const TextEditor::TabSettings &tabSettings) override;
int indentFor(const QTextBlock &block, const TextEditor::TabSettings &tabSettings) override;
- TextEditor::IndentationForBlock indentationForBlocks(const QVector<QTextBlock> &blocks,
- const TextEditor::TabSettings &tabSettings) override;
+ TextEditor::IndentationForBlock indentationForBlocks(
+ const QVector<QTextBlock> &blocks, const TextEditor::TabSettings &tabSettings) override;
};
} // namespace Internal
diff --git a/src/plugins/nim/editor/nimeditorfactory.cpp b/src/plugins/nim/editor/nimeditorfactory.cpp
index 91a57adcb2..c6f4f17dff 100644
--- a/src/plugins/nim/editor/nimeditorfactory.cpp
+++ b/src/plugins/nim/editor/nimeditorfactory.cpp
@@ -60,8 +60,8 @@ NimEditorFactory::NimEditorFactory()
setDocumentCreator([]() {
return new TextDocument(Constants::C_NIMEDITOR_ID);
});
- setIndenterCreator([]() {
- return new NimIndenter;
+ setIndenterCreator([](QTextDocument *doc) {
+ return new NimIndenter(doc);
});
setSyntaxHighlighterCreator([]() {
return new NimHighlighter;
@@ -80,7 +80,7 @@ Core::IEditor *NimEditorFactory::createEditor()
void NimEditorFactory::decorateEditor(TextEditorWidget *editor)
{
editor->textDocument()->setSyntaxHighlighter(new NimHighlighter());
- editor->textDocument()->setIndenter(new NimIndenter());
+ editor->textDocument()->setIndenter(new NimIndenter(editor->textDocument()->document()));
}
}
diff --git a/src/plugins/nim/editor/nimindenter.cpp b/src/plugins/nim/editor/nimindenter.cpp
index 8adf4a0730..0b61a4536b 100644
--- a/src/plugins/nim/editor/nimindenter.cpp
+++ b/src/plugins/nim/editor/nimindenter.cpp
@@ -37,7 +37,8 @@
namespace Nim {
-NimIndenter::NimIndenter()
+NimIndenter::NimIndenter(QTextDocument *doc)
+ : TextEditor::TextIndenter(doc)
{}
bool NimIndenter::isElectricCharacter(const QChar &ch) const
@@ -45,12 +46,10 @@ bool NimIndenter::isElectricCharacter(const QChar &ch) const
return NimIndenter::electricCharacters().contains(ch);
}
-void NimIndenter::indentBlock(QTextDocument *document,
- const QTextBlock &block,
+void NimIndenter::indentBlock(const QTextBlock &block,
const QChar &typedChar,
const TextEditor::TabSettings &settings)
{
- Q_UNUSED(document);
Q_UNUSED(typedChar);
const QString currentLine = block.text();
diff --git a/src/plugins/nim/editor/nimindenter.h b/src/plugins/nim/editor/nimindenter.h
index adf09c6a62..0342eda753 100644
--- a/src/plugins/nim/editor/nimindenter.h
+++ b/src/plugins/nim/editor/nimindenter.h
@@ -25,23 +25,24 @@
#pragma once
-#include <texteditor/indenter.h>
+#include <texteditor/textindenter.h>
-namespace TextEditor { class SimpleCodeStylePreferences; }
+namespace TextEditor {
+class SimpleCodeStylePreferences;
+}
namespace Nim {
class NimLexer;
-class NimIndenter : public TextEditor::Indenter
+class NimIndenter : public TextEditor::TextIndenter
{
public:
- NimIndenter();
+ explicit NimIndenter(QTextDocument *doc);
bool isElectricCharacter(const QChar &ch) const override;
- void indentBlock(QTextDocument *document,
- const QTextBlock &block,
+ void indentBlock(const QTextBlock &block,
const QChar &typedChar,
const TextEditor::TabSettings &settings) override;
@@ -51,9 +52,11 @@ private:
bool startsBlock(const QString &line, int state) const;
bool endsBlock(const QString &line, int state) const;
- int calculateIndentationDiff(const QString &previousLine, int previousState, int indentSize) const;
+ int calculateIndentationDiff(const QString &previousLine,
+ int previousState,
+ int indentSize) const;
- static QString rightTrimmed(const QString& other);
+ static QString rightTrimmed(const QString &other);
};
-}
+} // namespace Nim
diff --git a/src/plugins/nim/settings/nimcodestylepreferencesfactory.cpp b/src/plugins/nim/settings/nimcodestylepreferencesfactory.cpp
index 997622278e..299c6d13e5 100644
--- a/src/plugins/nim/settings/nimcodestylepreferencesfactory.cpp
+++ b/src/plugins/nim/settings/nimcodestylepreferencesfactory.cpp
@@ -67,9 +67,9 @@ QWidget *NimCodeStylePreferencesFactory::createEditor(TextEditor::ICodeStylePref
return result;
}
-TextEditor::Indenter *NimCodeStylePreferencesFactory::createIndenter() const
+TextEditor::Indenter *NimCodeStylePreferencesFactory::createIndenter(QTextDocument *doc) const
{
- return new NimIndenter();
+ return new NimIndenter(doc);
}
QString NimCodeStylePreferencesFactory::snippetProviderGroupId() const
diff --git a/src/plugins/nim/settings/nimcodestylepreferencesfactory.h b/src/plugins/nim/settings/nimcodestylepreferencesfactory.h
index 987ad253e3..e3d7ce3251 100644
--- a/src/plugins/nim/settings/nimcodestylepreferencesfactory.h
+++ b/src/plugins/nim/settings/nimcodestylepreferencesfactory.h
@@ -41,7 +41,7 @@ public:
TextEditor::ICodeStylePreferences *createCodeStyle() const override;
QWidget *createEditor(TextEditor::ICodeStylePreferences *settings,
QWidget *parent) const override;
- TextEditor::Indenter *createIndenter() const override;
+ TextEditor::Indenter *createIndenter(QTextDocument *doc) const override;
QString snippetProviderGroupId() const override;
QString previewText() const override;
};
diff --git a/src/plugins/nim/settings/nimcodestylepreferenceswidget.cpp b/src/plugins/nim/settings/nimcodestylepreferenceswidget.cpp
index 2f98932cc2..b4e735ff48 100644
--- a/src/plugins/nim/settings/nimcodestylepreferenceswidget.cpp
+++ b/src/plugins/nim/settings/nimcodestylepreferenceswidget.cpp
@@ -96,8 +96,7 @@ void NimCodeStylePreferencesWidget::updatePreview()
QTextCursor tc = m_ui->previewTextEdit->textCursor();
tc.beginEditBlock();
while (block.isValid()) {
- m_ui->previewTextEdit->textDocument()->indenter()
- ->indentBlock(doc, block, QChar::Null, ts);
+ m_ui->previewTextEdit->textDocument()->indenter()->indentBlock(block, QChar::Null, ts);
block = block.next();
}
tc.endEditBlock();
diff --git a/src/plugins/projectexplorer/jsonwizard/jsonwizardgeneratorfactory.cpp b/src/plugins/projectexplorer/jsonwizard/jsonwizardgeneratorfactory.cpp
index 013de06c0a..e0a06c824e 100644
--- a/src/plugins/projectexplorer/jsonwizard/jsonwizardgeneratorfactory.cpp
+++ b/src/plugins/projectexplorer/jsonwizard/jsonwizardgeneratorfactory.cpp
@@ -36,7 +36,6 @@
#include <coreplugin/dialogs/promptoverwritedialog.h>
#include <texteditor/icodestylepreferences.h>
#include <texteditor/icodestylepreferencesfactory.h>
-#include <texteditor/indenter.h>
#include <texteditor/normalindenter.h>
#include <texteditor/storagesettings.h>
#include <texteditor/tabsettings.h>
@@ -94,18 +93,22 @@ bool JsonWizardGenerator::formatFile(const JsonWizard *wizard, GeneratedFile *fi
auto baseProject = qobject_cast<Project *>(wizard->property("SelectedProject").value<QObject *>());
ICodeStylePreferencesFactory *factory = TextEditorSettings::codeStyleFactory(languageId);
+ QTextDocument doc(file->contents());
+ QTextCursor cursor(&doc);
Indenter *indenter = nullptr;
- if (factory)
- indenter = factory->createIndenter();
+ if (factory) {
+ indenter = factory->createIndenter(&doc);
+ indenter->setFileName(Utils::FileName::fromString(file->path()));
+ }
if (!indenter)
- indenter = new NormalIndenter();
-
+ indenter = new NormalIndenter(&doc);
ICodeStylePreferences *codeStylePrefs = codeStylePreferences(baseProject, languageId);
indenter->setCodeStylePreferences(codeStylePrefs);
- QTextDocument doc(file->contents());
- QTextCursor cursor(&doc);
+
cursor.select(QTextCursor::Document);
- indenter->indent(&doc, cursor, QChar::Null, codeStylePrefs->currentTabSettings());
+ indenter->indent(cursor,
+ QChar::Null,
+ codeStylePrefs->currentTabSettings());
delete indenter;
if (TextEditorSettings::storageSettings().m_cleanWhitespace) {
QTextBlock block = doc.firstBlock();
diff --git a/src/plugins/projectexplorer/projectfilewizardextension.cpp b/src/plugins/projectexplorer/projectfilewizardextension.cpp
index 4b4ecaeb30..5dab7bbf99 100644
--- a/src/plugins/projectexplorer/projectfilewizardextension.cpp
+++ b/src/plugins/projectexplorer/projectfilewizardextension.cpp
@@ -252,18 +252,23 @@ void ProjectFileWizardExtension::applyCodeStyle(GeneratedFile *file) const
ICodeStylePreferencesFactory *factory = TextEditorSettings::codeStyleFactory(languageId);
+ QTextDocument doc(file->contents());
Indenter *indenter = nullptr;
- if (factory)
- indenter = factory->createIndenter();
+ if (factory) {
+ indenter = factory->createIndenter(&doc);
+ indenter->setFileName(Utils::FileName::fromString(file->path()));
+ }
if (!indenter)
- indenter = new NormalIndenter();
+ indenter = new NormalIndenter(&doc);
ICodeStylePreferences *codeStylePrefs = codeStylePreferences(baseProject, languageId);
indenter->setCodeStylePreferences(codeStylePrefs);
- QTextDocument doc(file->contents());
+
QTextCursor cursor(&doc);
cursor.select(QTextCursor::Document);
- indenter->indent(&doc, cursor, QChar::Null, codeStylePrefs->currentTabSettings());
+ indenter->indent(cursor,
+ QChar::Null,
+ codeStylePrefs->currentTabSettings());
delete indenter;
if (TextEditorSettings::storageSettings().m_cleanWhitespace) {
QTextBlock block = doc.firstBlock();
diff --git a/src/plugins/pythoneditor/pythoneditor.cpp b/src/plugins/pythoneditor/pythoneditor.cpp
index 4c8b95ad92..d0f27ae63c 100644
--- a/src/plugins/pythoneditor/pythoneditor.cpp
+++ b/src/plugins/pythoneditor/pythoneditor.cpp
@@ -54,7 +54,7 @@ PythonEditorFactory::PythonEditorFactory()
| TextEditorActionHandler::FollowSymbolUnderCursor);
setDocumentCreator([] { return new TextDocument(Constants::C_PYTHONEDITOR_ID); });
- setIndenterCreator([] { return new PythonIndenter; });
+ setIndenterCreator([](QTextDocument *doc) { return new PythonIndenter(doc); });
setSyntaxHighlighterCreator([] { return new PythonHighlighter; });
setCommentDefinition(Utils::CommentDefinition::HashStyle);
setParenthesesMatchingEnabled(true);
diff --git a/src/plugins/pythoneditor/pythonindenter.cpp b/src/plugins/pythoneditor/pythonindenter.cpp
index 035f1aef7c..ee7813f327 100644
--- a/src/plugins/pythoneditor/pythonindenter.cpp
+++ b/src/plugins/pythoneditor/pythonindenter.cpp
@@ -50,6 +50,10 @@ static QTextBlock previousNonEmptyBlock(const QTextBlock &block)
return result;
}
+PythonIndenter::PythonIndenter(QTextDocument *doc)
+ : TextEditor::TextIndenter(doc)
+{}
+
/**
* @brief Does given character change indentation level?
* @param ch Any value
diff --git a/src/plugins/pythoneditor/pythonindenter.h b/src/plugins/pythoneditor/pythonindenter.h
index 414c5dcb25..8ce10ba4fe 100644
--- a/src/plugins/pythoneditor/pythonindenter.h
+++ b/src/plugins/pythoneditor/pythonindenter.h
@@ -25,12 +25,14 @@
#pragma once
-#include <texteditor/indenter.h>
+#include <texteditor/textindenter.h>
namespace PythonEditor {
-class PythonIndenter : public TextEditor::Indenter
+class PythonIndenter : public TextEditor::TextIndenter
{
+public:
+ explicit PythonIndenter(QTextDocument *doc);
private:
bool isElectricCharacter(const QChar &ch) const override;
int indentFor(const QTextBlock &block, const TextEditor::TabSettings &tabSettings) override;
diff --git a/src/plugins/qmldesigner/designercore/model/basetexteditmodifier.cpp b/src/plugins/qmldesigner/designercore/model/basetexteditmodifier.cpp
index 612f3003e5..a5fddccba9 100644
--- a/src/plugins/qmldesigner/designercore/model/basetexteditmodifier.cpp
+++ b/src/plugins/qmldesigner/designercore/model/basetexteditmodifier.cpp
@@ -61,8 +61,8 @@ void BaseTextEditModifier::indentLines(int startLine, int endLine)
QTextBlock start = textDocument->findBlockByNumber(i);
if (start.isValid()) {
- QmlJSEditor::Internal::Indenter indenter;
- indenter.indentBlock(textDocument, start, QChar::Null, tabSettings);
+ QmlJSEditor::Internal::Indenter indenter(textDocument);
+ indenter.indentBlock(start, QChar::Null, tabSettings);
}
}
tc.endEditBlock();
diff --git a/src/plugins/qmljseditor/qmljseditor.cpp b/src/plugins/qmljseditor/qmljseditor.cpp
index dadd9bee60..ee3f30b2fe 100644
--- a/src/plugins/qmljseditor/qmljseditor.cpp
+++ b/src/plugins/qmljseditor/qmljseditor.cpp
@@ -1071,7 +1071,7 @@ QmlJSEditorFactory::QmlJSEditorFactory()
void QmlJSEditorFactory::decorateEditor(TextEditorWidget *editor)
{
editor->textDocument()->setSyntaxHighlighter(new QmlJSHighlighter);
- editor->textDocument()->setIndenter(new Indenter);
+ editor->textDocument()->setIndenter(new Indenter(editor->textDocument()->document()));
editor->setAutoCompleter(new AutoCompleter);
}
diff --git a/src/plugins/qmljseditor/qmljseditordocument.cpp b/src/plugins/qmljseditor/qmljseditordocument.cpp
index ae18e6a573..2f30f324cb 100644
--- a/src/plugins/qmljseditor/qmljseditordocument.cpp
+++ b/src/plugins/qmljseditor/qmljseditordocument.cpp
@@ -653,7 +653,7 @@ QmlJSEditorDocument::QmlJSEditorDocument()
connect(this, &TextEditor::TextDocument::tabSettingsChanged,
d, &Internal::QmlJSEditorDocumentPrivate::invalidateFormatterCache);
setSyntaxHighlighter(new QmlJSHighlighter(document()));
- setIndenter(new Internal::Indenter);
+ setIndenter(new Internal::Indenter(document()));
}
QmlJSEditorDocument::~QmlJSEditorDocument()
diff --git a/src/plugins/qmljseditor/quicktoolbar.cpp b/src/plugins/qmljseditor/quicktoolbar.cpp
index 89c6dc349b..15dec5a80c 100644
--- a/src/plugins/qmljseditor/quicktoolbar.cpp
+++ b/src/plugins/qmljseditor/quicktoolbar.cpp
@@ -421,8 +421,8 @@ void QuickToolBar::indentLines(int startLine, int endLine)
QTextBlock start = m_editorWidget->document()->findBlockByNumber(i);
if (start.isValid()) {
- QmlJSEditor::Internal::Indenter indenterMy;
- indenterMy.indentBlock(m_editorWidget->document(), start, QChar::Null, tabSettings);
+ QmlJSEditor::Internal::Indenter indenterMy(m_editorWidget->document());
+ indenterMy.indentBlock(start, QChar::Null, tabSettings);
}
}
}
diff --git a/src/plugins/qmljstools/qmljscodestylepreferencesfactory.cpp b/src/plugins/qmljstools/qmljscodestylepreferencesfactory.cpp
index f49f88929f..3ca3bbc999 100644
--- a/src/plugins/qmljstools/qmljscodestylepreferencesfactory.cpp
+++ b/src/plugins/qmljstools/qmljscodestylepreferencesfactory.cpp
@@ -80,9 +80,9 @@ QWidget *QmlJSCodeStylePreferencesFactory::createEditor(TextEditor::ICodeStylePr
return widget;
}
-TextEditor::Indenter *QmlJSCodeStylePreferencesFactory::createIndenter() const
+TextEditor::Indenter *QmlJSCodeStylePreferencesFactory::createIndenter(QTextDocument *doc) const
{
- return new QmlJSEditor::Internal::Indenter();
+ return new QmlJSEditor::Internal::Indenter(doc);
}
QString QmlJSCodeStylePreferencesFactory::snippetProviderGroupId() const
diff --git a/src/plugins/qmljstools/qmljscodestylepreferencesfactory.h b/src/plugins/qmljstools/qmljscodestylepreferencesfactory.h
index 18f40a98d3..111103f243 100644
--- a/src/plugins/qmljstools/qmljscodestylepreferencesfactory.h
+++ b/src/plugins/qmljstools/qmljscodestylepreferencesfactory.h
@@ -39,7 +39,7 @@ public:
TextEditor::ICodeStylePreferences *createCodeStyle() const override;
QWidget *createEditor(TextEditor::ICodeStylePreferences *settings,
QWidget *parent) const override;
- TextEditor::Indenter *createIndenter() const override;
+ TextEditor::Indenter *createIndenter(QTextDocument *doc) const override;
QString snippetProviderGroupId() const override;
QString previewText() const override;
};
diff --git a/src/plugins/qmljstools/qmljscodestylesettingspage.cpp b/src/plugins/qmljstools/qmljscodestylesettingspage.cpp
index f13ac29f75..2de503b782 100644
--- a/src/plugins/qmljstools/qmljscodestylesettingspage.cpp
+++ b/src/plugins/qmljstools/qmljscodestylesettingspage.cpp
@@ -113,8 +113,7 @@ void QmlJSCodeStylePreferencesWidget::updatePreview()
QTextCursor tc = m_ui->previewTextEdit->textCursor();
tc.beginEditBlock();
while (block.isValid()) {
- m_ui->previewTextEdit->textDocument()->indenter()
- ->indentBlock(doc, block, QChar::Null, ts);
+ m_ui->previewTextEdit->textDocument()->indenter()->indentBlock(block, QChar::Null, ts);
block = block.next();
}
tc.endEditBlock();
diff --git a/src/plugins/qmljstools/qmljsindenter.cpp b/src/plugins/qmljstools/qmljsindenter.cpp
index 416267e695..3e156d756e 100644
--- a/src/plugins/qmljstools/qmljsindenter.cpp
+++ b/src/plugins/qmljstools/qmljsindenter.cpp
@@ -35,7 +35,9 @@
using namespace QmlJSEditor;
using namespace Internal;
-Indenter::Indenter() = default;
+Indenter::Indenter(QTextDocument *doc)
+ : TextEditor::TextIndenter(doc)
+{}
Indenter::~Indenter() = default;
@@ -49,13 +51,10 @@ bool Indenter::isElectricCharacter(const QChar &ch) const
return false;
}
-void Indenter::indentBlock(QTextDocument *doc,
- const QTextBlock &block,
+void Indenter::indentBlock(const QTextBlock &block,
const QChar &typedChar,
const TextEditor::TabSettings &tabSettings)
{
- Q_UNUSED(doc)
-
const int depth = indentFor(block, tabSettings);
if (depth == -1)
return;
@@ -74,29 +73,24 @@ void Indenter::indentBlock(QTextDocument *doc,
tabSettings.indentLine(block, depth);
}
-void Indenter::invalidateCache(QTextDocument *doc)
+void Indenter::invalidateCache()
{
QmlJSTools::CreatorCodeFormatter codeFormatter;
- codeFormatter.invalidateCache(doc);
+ codeFormatter.invalidateCache(m_doc);
}
-
-int Indenter::indentFor(const QTextBlock &block,
- const TextEditor::TabSettings &tabSettings)
+int Indenter::indentFor(const QTextBlock &block, const TextEditor::TabSettings &tabSettings)
{
QmlJSTools::CreatorCodeFormatter codeFormatter(tabSettings);
codeFormatter.updateStateUntil(block);
return codeFormatter.indentFor(block);
}
-
-TextEditor::IndentationForBlock
-Indenter::indentationForBlocks(const QVector<QTextBlock> &blocks,
- const TextEditor::TabSettings &tabSettings)
+TextEditor::IndentationForBlock Indenter::indentationForBlocks(
+ const QVector<QTextBlock> &blocks, const TextEditor::TabSettings &tabSettings)
{
QmlJSTools::CreatorCodeFormatter codeFormatter(tabSettings);
-
codeFormatter.updateStateUntil(blocks.last());
TextEditor::IndentationForBlock ret;
diff --git a/src/plugins/qmljstools/qmljsindenter.h b/src/plugins/qmljstools/qmljsindenter.h
index 1c82a1b18c..3a51790556 100644
--- a/src/plugins/qmljstools/qmljsindenter.h
+++ b/src/plugins/qmljstools/qmljsindenter.h
@@ -27,27 +27,26 @@
#include "qmljstools_global.h"
-#include <texteditor/indenter.h>
+#include <texteditor/textindenter.h>
namespace QmlJSEditor {
namespace Internal {
-class QMLJSTOOLS_EXPORT Indenter : public TextEditor::Indenter
+class QMLJSTOOLS_EXPORT Indenter : public TextEditor::TextIndenter
{
public:
- Indenter();
+ explicit Indenter(QTextDocument *doc);
~Indenter() override;
bool isElectricCharacter(const QChar &ch) const override;
- void indentBlock(QTextDocument *doc,
- const QTextBlock &block,
+ void indentBlock(const QTextBlock &block,
const QChar &typedChar,
const TextEditor::TabSettings &tabSettings) override;
- void invalidateCache(QTextDocument *doc) override;
+ void invalidateCache() override;
int indentFor(const QTextBlock &block, const TextEditor::TabSettings &tabSettings) override;
- TextEditor::IndentationForBlock indentationForBlocks(const QVector<QTextBlock> &blocks,
- const TextEditor::TabSettings &tabSettings) override;
+ TextEditor::IndentationForBlock indentationForBlocks(
+ const QVector<QTextBlock> &blocks, const TextEditor::TabSettings &tabSettings) override;
};
} // Internal
diff --git a/src/plugins/qmljstools/qmljsrefactoringchanges.cpp b/src/plugins/qmljstools/qmljsrefactoringchanges.cpp
index b27631c2d0..3fda024e4e 100644
--- a/src/plugins/qmljstools/qmljsrefactoringchanges.cpp
+++ b/src/plugins/qmljstools/qmljsrefactoringchanges.cpp
@@ -77,8 +77,8 @@ public:
const TextEditor::TabSettings &tabSettings =
ProjectExplorer::actualTabSettings(fileName, textDocument);
- QmlJSEditor::Internal::Indenter indenter;
- indenter.reindent(selection.document(), selection, tabSettings);
+ QmlJSEditor::Internal::Indenter indenter(selection.document());
+ indenter.reindent(selection, tabSettings);
}
void fileChanged(const QString &fileName) override
diff --git a/src/plugins/texteditor/codestyleeditor.cpp b/src/plugins/texteditor/codestyleeditor.cpp
index cbf74c0a12..edfc40d12b 100644
--- a/src/plugins/texteditor/codestyleeditor.cpp
+++ b/src/plugins/texteditor/codestyleeditor.cpp
@@ -83,14 +83,15 @@ void CodeStyleEditor::updatePreview()
{
QTextDocument *doc = m_preview->document();
- m_preview->textDocument()->indenter()->invalidateCache(doc);
+ m_preview->textDocument()->indenter()->invalidateCache();
QTextBlock block = doc->firstBlock();
QTextCursor tc = m_preview->textCursor();
tc.beginEditBlock();
while (block.isValid()) {
- m_preview->textDocument()->indenter()
- ->indentBlock(doc, block, QChar::Null, m_codeStyle->currentTabSettings());
+ m_preview->textDocument()->indenter()->indentBlock(block,
+ QChar::Null,
+ m_codeStyle->currentTabSettings());
block = block.next();
}
tc.endEditBlock();
diff --git a/src/plugins/texteditor/icodestylepreferencesfactory.h b/src/plugins/texteditor/icodestylepreferencesfactory.h
index 43cc6edffd..2acc0a5fa4 100644
--- a/src/plugins/texteditor/icodestylepreferencesfactory.h
+++ b/src/plugins/texteditor/icodestylepreferencesfactory.h
@@ -27,13 +27,14 @@
#include "texteditor_global.h"
+#include "indenter.h"
+
#include <QObject>
namespace Core { class Id; }
namespace TextEditor {
class ICodeStylePreferences;
-class Indenter;
class SnippetProvider;
class TEXTEDITOR_EXPORT ICodeStylePreferencesFactory : public QObject
@@ -48,7 +49,7 @@ public:
virtual QString displayName() = 0;
virtual ICodeStylePreferences *createCodeStyle() const = 0;
virtual QWidget *createEditor(ICodeStylePreferences *preferences, QWidget *parent) const = 0;
- virtual TextEditor::Indenter *createIndenter() const = 0;
+ virtual TextEditor::Indenter *createIndenter(QTextDocument *doc) const = 0;
virtual QString snippetProviderGroupId() const = 0;
virtual QString previewText() const = 0;
};
diff --git a/src/plugins/texteditor/indenter.h b/src/plugins/texteditor/indenter.h
index 300e92a135..5b4b97fbfa 100644
--- a/src/plugins/texteditor/indenter.h
+++ b/src/plugins/texteditor/indenter.h
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2016 The Qt Company Ltd.
+** Copyright (C) 2019 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of Qt Creator.
@@ -25,21 +25,16 @@
#pragma once
-#include "texteditor_global.h"
-
-#include "tabsettings.h"
+#include <utils/fileutils.h>
+#include <utils/optional.h>
#include <QMap>
+#include <QTextBlock>
#include <vector>
-QT_BEGIN_NAMESPACE
-class QTextDocument;
-class QTextCursor;
-class QTextBlock;
-class QChar;
-QT_END_NAMESPACE
-
-namespace Utils { class FileName; }
+namespace Utils {
+class FileName;
+}
namespace TextEditor {
@@ -48,7 +43,7 @@ class TabSettings;
using IndentationForBlock = QMap<int, int>;
-class TEXTEDITOR_EXPORT Replacement
+class Replacement
{
public:
Replacement(int offset, int length, const QString &text)
@@ -63,50 +58,57 @@ public:
using Replacements = std::vector<Replacement>;
-class TEXTEDITOR_EXPORT Indenter
+class Indenter
{
public:
- Indenter();
- virtual ~Indenter();
+ explicit Indenter(QTextDocument *doc)
+ : m_doc(doc)
+ {}
+
+ void setFileName(const Utils::FileName &fileName) { m_fileName = fileName; }
+
+ virtual ~Indenter() = default;
// Returns true if key triggers an indent.
- virtual bool isElectricCharacter(const QChar &ch) const;
+ virtual bool isElectricCharacter(const QChar & /*ch*/) const { return false; }
+
+ virtual void setCodeStylePreferences(ICodeStylePreferences * /*preferences*/) {}
+
+ virtual void invalidateCache() {}
+
+ virtual int indentFor(const QTextBlock & /*block*/, const TabSettings & /*tabSettings*/)
+ {
+ return -1;
+ }
+
+ // Expects a list of blocks in order of occurrence in the document.
+ virtual IndentationForBlock indentationForBlocks(const QVector<QTextBlock> &blocks,
+ const TabSettings & /*tabSettings*/)
+ = 0;
+ virtual Utils::optional<TabSettings> tabSettings() const = 0;
// Indent a text block based on previous line. Default does nothing
- virtual void indentBlock(QTextDocument *doc,
- const QTextBlock &block,
+ virtual void indentBlock(const QTextBlock &block,
const QChar &typedChar,
- const TabSettings &tabSettings);
+ const TabSettings &tabSettings)
+ = 0;
// Indent at cursor. Calls indentBlock for selection or current line.
- virtual void indent(QTextDocument *doc,
- const QTextCursor &cursor,
+ virtual void indent(const QTextCursor &cursor,
const QChar &typedChar,
- const TabSettings &tabSettings,
- bool autoTriggered = true);
+ const TabSettings &tabSettings)
+ = 0;
// By default just calls indent with default settings.
- virtual Replacements format(QTextDocument *doc,
- const Utils::FileName &fileName,
- const QTextCursor &cursor,
- const TabSettings &tabSettings);
+ virtual Replacements format(const QTextCursor &cursor, const TabSettings &tabSettings) = 0;
// 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);
-
- virtual void setCodeStylePreferences(ICodeStylePreferences *preferences);
-
- virtual void invalidateCache(QTextDocument *doc);
-
- virtual int indentFor(const QTextBlock &block, const TextEditor::TabSettings &tabSettings);
-
- // Expects a list of blocks in order of occurrence in the document.
- virtual IndentationForBlock indentationForBlocks(const QVector<QTextBlock> &blocks,
- const TextEditor::TabSettings &tabSettings);
+ virtual void reindent(const QTextCursor &cursor, const TabSettings &tabSettings) = 0;
- virtual bool hasTabSettings() const { return false; }
- virtual TabSettings tabSettings() const { return TabSettings(); }
+protected:
+ QTextDocument *m_doc;
+ Utils::FileName m_fileName;
};
} // namespace TextEditor
diff --git a/src/plugins/texteditor/normalindenter.cpp b/src/plugins/texteditor/normalindenter.cpp
index d1956d83d8..7faea84c48 100644
--- a/src/plugins/texteditor/normalindenter.cpp
+++ b/src/plugins/texteditor/normalindenter.cpp
@@ -50,6 +50,10 @@
using namespace TextEditor;
+NormalIndenter::NormalIndenter(QTextDocument *doc)
+ : TextIndenter(doc)
+{}
+
int NormalIndenter::indentFor(const QTextBlock &block, const TabSettings &tabSettings)
{
Q_UNUSED(tabSettings);
diff --git a/src/plugins/texteditor/normalindenter.h b/src/plugins/texteditor/normalindenter.h
index 119c2b8f66..ece41fa52d 100644
--- a/src/plugins/texteditor/normalindenter.h
+++ b/src/plugins/texteditor/normalindenter.h
@@ -25,14 +25,14 @@
#pragma once
-#include "indenter.h"
+#include "textindenter.h"
namespace TextEditor {
-class TEXTEDITOR_EXPORT NormalIndenter : public Indenter
+class TEXTEDITOR_EXPORT NormalIndenter : public TextIndenter
{
public:
- NormalIndenter() = default;
+ explicit NormalIndenter(QTextDocument *doc);
~NormalIndenter() override = default;
int indentFor(const QTextBlock &block, const TabSettings &tabSettings) override;
diff --git a/src/plugins/texteditor/plaintexteditorfactory.cpp b/src/plugins/texteditor/plaintexteditorfactory.cpp
index f585115e7f..02e89b4227 100644
--- a/src/plugins/texteditor/plaintexteditorfactory.cpp
+++ b/src/plugins/texteditor/plaintexteditorfactory.cpp
@@ -65,7 +65,7 @@ PlainTextEditorFactory::PlainTextEditorFactory()
setDocumentCreator([]() { return new TextDocument(Core::Constants::K_DEFAULT_TEXT_EDITOR_ID); });
setEditorWidgetCreator([]() { return new PlainTextEditorWidget; });
- setIndenterCreator([]() { return new NormalIndenter; });
+ setIndenterCreator([](QTextDocument *doc) { return new NormalIndenter(doc); });
setUseGenericHighlighter(true);
setEditorActionHandlers(TextEditorActionHandler::Format |
diff --git a/src/plugins/texteditor/textdocument.cpp b/src/plugins/texteditor/textdocument.cpp
index 7edbdd1488..ef504447a5 100644
--- a/src/plugins/texteditor/textdocument.cpp
+++ b/src/plugins/texteditor/textdocument.cpp
@@ -27,7 +27,7 @@
#include "extraencodingsettings.h"
#include "fontsettings.h"
-#include "indenter.h"
+#include "textindenter.h"
#include "storagesettings.h"
#include "syntaxhighlighter.h"
#include "tabsettings.h"
@@ -78,7 +78,7 @@ class TextDocumentPrivate
{
public:
TextDocumentPrivate()
- : m_indenter(new Indenter)
+ : m_indenter(new TextIndenter(&m_document))
{
}
@@ -416,19 +416,19 @@ void TextDocument::setExtraEncodingSettings(const ExtraEncodingSettings &extraEn
d->m_extraEncodingSettings = extraEncodingSettings;
}
-void TextDocument::autoIndent(const QTextCursor &cursor, QChar typedChar, bool autoTriggered)
+void TextDocument::autoIndent(const QTextCursor &cursor, QChar typedChar)
{
- d->m_indenter->indent(&d->m_document, cursor, typedChar, tabSettings(), autoTriggered);
+ d->m_indenter->indent(cursor, typedChar, tabSettings());
}
void TextDocument::autoReindent(const QTextCursor &cursor)
{
- d->m_indenter->reindent(&d->m_document, cursor, tabSettings());
+ d->m_indenter->reindent(cursor, tabSettings());
}
void TextDocument::autoFormat(const QTextCursor &cursor)
{
- d->m_indenter->format(&d->m_document, filePath(), cursor, tabSettings());
+ d->m_indenter->format(cursor, tabSettings());
}
QTextCursor TextDocument::indent(const QTextCursor &cursor, bool blockSelection, int column,
@@ -824,8 +824,8 @@ void TextDocument::cleanWhitespace(QTextCursor &cursor, bool cleanIndentation, b
return;
const TabSettings currentTabSettings = tabSettings();
- const IndentationForBlock &indentations =
- d->m_indenter->indentationForBlocks(blocks, currentTabSettings);
+ const IndentationForBlock &indentations
+ = d->m_indenter->indentationForBlocks(blocks, currentTabSettings);
foreach (block, blocks) {
QString blockText = block.text();
diff --git a/src/plugins/texteditor/textdocument.h b/src/plugins/texteditor/textdocument.h
index f293b3aeaa..eaa102ec74 100644
--- a/src/plugins/texteditor/textdocument.h
+++ b/src/plugins/texteditor/textdocument.h
@@ -26,6 +26,7 @@
#pragma once
#include "texteditor_global.h"
+#include "indenter.h"
#include <coreplugin/id.h>
#include <coreplugin/textdocument.h>
@@ -48,7 +49,6 @@ namespace TextEditor {
class CompletionAssistProvider;
class ExtraEncodingSettings;
class FontSettings;
-class Indenter;
class IAssistProvider;
class StorageSettings;
class SyntaxHighlighter;
@@ -87,8 +87,7 @@ public:
void setIndenter(Indenter *indenter);
Indenter *indenter() const;
- void autoIndent(const QTextCursor &cursor, QChar typedChar = QChar::Null,
- bool autoTriggered = true);
+ void autoIndent(const QTextCursor &cursor, QChar typedChar = QChar::Null);
void autoReindent(const QTextCursor &cursor);
void autoFormat(const QTextCursor &cursor);
QTextCursor indent(const QTextCursor &cursor, bool blockSelection = false, int column = 0,
diff --git a/src/plugins/texteditor/texteditor.cpp b/src/plugins/texteditor/texteditor.cpp
index e2d46141fb..d7ceb83144 100644
--- a/src/plugins/texteditor/texteditor.cpp
+++ b/src/plugins/texteditor/texteditor.cpp
@@ -8738,7 +8738,7 @@ IEditor *TextEditorFactory::createEditor()
TextDocumentPtr doc(d->m_documentCreator());
if (d->m_indenterCreator)
- doc->setIndenter(d->m_indenterCreator());
+ doc->setIndenter(d->m_indenterCreator(doc->document()));
if (d->m_syntaxHighlighterCreator)
doc->setSyntaxHighlighter(d->m_syntaxHighlighterCreator());
diff --git a/src/plugins/texteditor/texteditor.h b/src/plugins/texteditor/texteditor.h
index 8615f15295..8ea2606bd2 100644
--- a/src/plugins/texteditor/texteditor.h
+++ b/src/plugins/texteditor/texteditor.h
@@ -27,6 +27,7 @@
#include "texteditor_global.h"
#include "blockrange.h"
+#include "indenter.h"
#include "codeassist/assistenums.h"
#include <coreplugin/editormanager/editormanager.h>
@@ -85,7 +86,6 @@ class CompletionSettings;
class DisplaySettings;
class ExtraEncodingSettings;
class FontSettings;
-class Indenter;
class MarginSettings;
class StorageSettings;
class TypingSettings;
@@ -635,7 +635,7 @@ public:
using DocumentCreator = std::function<TextDocument *()>;
using EditorWidgetCreator = std::function<TextEditorWidget *()>;
using SyntaxHighLighterCreator = std::function<SyntaxHighlighter *()>;
- using IndenterCreator = std::function<Indenter *()>;
+ using IndenterCreator = std::function<Indenter *(QTextDocument *)>;
using AutoCompleterCreator = std::function<AutoCompleter *()>;
void setDocumentCreator(const DocumentCreator &creator);
diff --git a/src/plugins/texteditor/texteditor.pro b/src/plugins/texteditor/texteditor.pro
index 9b698b7340..d9f99ccc9d 100644
--- a/src/plugins/texteditor/texteditor.pro
+++ b/src/plugins/texteditor/texteditor.pro
@@ -31,7 +31,7 @@ SOURCES += texteditorplugin.cpp \
textdocumentlayout.cpp \
completionsettings.cpp \
normalindenter.cpp \
- indenter.cpp \
+ textindenter.cpp \
quickfix.cpp \
syntaxhighlighter.cpp \
highlighterutils.cpp \
@@ -135,7 +135,7 @@ HEADERS += texteditorplugin.h \
textdocumentlayout.h \
completionsettings.h \
normalindenter.h \
- indenter.h \
+ textindenter.h \
quickfix.h \
syntaxhighlighter.h \
highlighterutils.h \
@@ -218,7 +218,8 @@ HEADERS += texteditorplugin.h \
commentssettings.h \
textstyles.h \
formattexteditor.h \
- command.h
+ command.h \
+ indenter.h
FORMS += \
displaysettingspage.ui \
diff --git a/src/plugins/texteditor/texteditor.qbs b/src/plugins/texteditor/texteditor.qbs
index 052a8f13fb..01fbcc68ab 100644
--- a/src/plugins/texteditor/texteditor.qbs
+++ b/src/plugins/texteditor/texteditor.qbs
@@ -88,7 +88,6 @@ Project {
"icodestylepreferences.h",
"icodestylepreferencesfactory.cpp",
"icodestylepreferencesfactory.h",
- "indenter.cpp",
"indenter.h",
"ioutlinewidget.h",
"linenumberfilter.cpp",
@@ -143,6 +142,8 @@ Project {
"texteditorplugin.h",
"texteditorsettings.cpp",
"texteditorsettings.h",
+ "textindenter.cpp",
+ "textindenter.h",
"textmark.cpp",
"textmark.h",
"textstyles.h",
diff --git a/src/plugins/texteditor/indenter.cpp b/src/plugins/texteditor/textindenter.cpp
index 6f0dce63cf..bca7b1ae18 100644
--- a/src/plugins/texteditor/indenter.cpp
+++ b/src/plugins/texteditor/textindenter.cpp
@@ -23,30 +23,32 @@
**
****************************************************************************/
-#include "indenter.h"
-#include "tabsettings.h"
-#include "textdocumentlayout.h"
+#include "textindenter.h"
#include <QTextDocument>
#include <QTextCursor>
using namespace TextEditor;
-Indenter::Indenter() = default;
+TextIndenter::TextIndenter(QTextDocument *doc)
+ : Indenter(doc)
+{}
-Indenter::~Indenter() = default;
+TextIndenter::~TextIndenter() = default;
-bool Indenter::isElectricCharacter(const QChar &) const
+IndentationForBlock TextIndenter::indentationForBlocks(const QVector<QTextBlock> &blocks,
+ const TabSettings &tabSettings)
{
- return false;
+ IndentationForBlock ret;
+ for (QTextBlock block : blocks)
+ ret.insert(block.blockNumber(), indentFor(block, tabSettings));
+ return ret;
}
-void Indenter::indentBlock(QTextDocument *doc,
- const QTextBlock &block,
- const QChar &typedChar,
- const TabSettings &tabSettings)
+void TextIndenter::indentBlock(const QTextBlock &block,
+ const QChar &typedChar,
+ const TabSettings &tabSettings)
{
- Q_UNUSED(doc);
Q_UNUSED(typedChar);
const int indent = indentFor(block, tabSettings);
if (indent < 0)
@@ -54,41 +56,39 @@ void Indenter::indentBlock(QTextDocument *doc,
tabSettings.indentLine(block, indent);
}
-void Indenter::indent(QTextDocument *doc,
- const QTextCursor &cursor,
- const QChar &typedChar,
- const TabSettings &tabSettings,
- bool /*autoTriggered*/)
+void TextIndenter::indent(const QTextCursor &cursor,
+ const QChar &typedChar,
+ const TabSettings &tabSettings)
{
if (cursor.hasSelection()) {
- QTextBlock block = doc->findBlock(cursor.selectionStart());
- const QTextBlock end = doc->findBlock(cursor.selectionEnd()).next();
+ QTextBlock block = m_doc->findBlock(cursor.selectionStart());
+ const QTextBlock end = m_doc->findBlock(cursor.selectionEnd()).next();
do {
- indentBlock(doc, block, typedChar, tabSettings);
+ indentBlock(block, typedChar, tabSettings);
block = block.next();
} while (block.isValid() && block != end);
} else {
- indentBlock(doc, cursor.block(), typedChar, tabSettings);
+ indentBlock(cursor.block(), typedChar, tabSettings);
}
}
-void Indenter::reindent(QTextDocument *doc, const QTextCursor &cursor, const TabSettings &tabSettings)
+void TextIndenter::reindent(const QTextCursor &cursor, const TabSettings &tabSettings)
{
if (cursor.hasSelection()) {
- QTextBlock block = doc->findBlock(cursor.selectionStart());
- const QTextBlock end = doc->findBlock(cursor.selectionEnd()).next();
+ QTextBlock block = m_doc->findBlock(cursor.selectionStart());
+ const QTextBlock end = m_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);
+ indentBlock(block, QChar::Null, tabSettings);
block = block.next();
}
int previousIndentation = tabSettings.indentationColumn(block.text());
- indentBlock(doc, block, QChar::Null, tabSettings);
+ indentBlock(block, QChar::Null, tabSettings);
int currentIndentation = tabSettings.indentationColumn(block.text());
int delta = currentIndentation - previousIndentation;
@@ -98,40 +98,17 @@ void Indenter::reindent(QTextDocument *doc, const QTextCursor &cursor, const Tab
block = block.next();
}
} else {
- indentBlock(doc, cursor.block(), QChar::Null, tabSettings);
+ indentBlock(cursor.block(), QChar::Null, tabSettings);
}
}
-Replacements Indenter::format(QTextDocument *doc,
- const Utils::FileName & /*fileName*/,
- const QTextCursor &cursor,
- const TabSettings &tabSettings)
+Replacements TextIndenter::format(const QTextCursor &cursor, const TabSettings &tabSettings)
{
- indent(doc, cursor, QChar::Null, tabSettings);
+ indent(cursor, QChar::Null, tabSettings);
return Replacements();
}
-void Indenter::setCodeStylePreferences(ICodeStylePreferences *)
-{
-
-}
-
-void Indenter::invalidateCache(QTextDocument *)
-{
-}
-
-int Indenter::indentFor(const QTextBlock &block, const TabSettings &tabSettings)
-{
- Q_UNUSED(block)
- Q_UNUSED(tabSettings)
- return -1;
-}
-
-IndentationForBlock Indenter::indentationForBlocks(const QVector<QTextBlock> &blocks,
- const TabSettings &tabSettings)
+Utils::optional<TabSettings> TextIndenter::tabSettings() const
{
- IndentationForBlock ret;
- foreach (QTextBlock block, blocks)
- ret.insert(block.blockNumber(), indentFor(block, tabSettings));
- return ret;
+ return Utils::optional<TabSettings>();
}
diff --git a/src/plugins/texteditor/textindenter.h b/src/plugins/texteditor/textindenter.h
new file mode 100644
index 0000000000..8a87b9214d
--- /dev/null
+++ b/src/plugins/texteditor/textindenter.h
@@ -0,0 +1,63 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt Creator.
+**
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+****************************************************************************/
+
+#pragma once
+
+#include "texteditor_global.h"
+
+#include "indenter.h"
+#include "tabsettings.h"
+
+QT_BEGIN_NAMESPACE
+class QTextDocument;
+class QTextCursor;
+class QChar;
+QT_END_NAMESPACE
+
+namespace TextEditor {
+
+class TEXTEDITOR_EXPORT TextIndenter : public Indenter
+{
+public:
+ explicit TextIndenter(QTextDocument *doc);
+ ~TextIndenter() override;
+
+ IndentationForBlock indentationForBlocks(const QVector<QTextBlock> &blocks,
+ const TabSettings &tabSettings) override;
+ void indentBlock(const QTextBlock &block,
+ const QChar &typedChar,
+ const TabSettings &tabSettings) override;
+
+ void indent(const QTextCursor &cursor,
+ const QChar &typedChar,
+ const TabSettings &tabSettings) override;
+
+ Replacements format(const QTextCursor &cursor, const TabSettings &tabSettings) override;
+
+ void reindent(const QTextCursor &cursor, const TabSettings &tabSettings) override;
+ Utils::optional<TabSettings> tabSettings() const override;
+};
+
+} // namespace TextEditor
diff --git a/src/shared/clang/clang_installation.pri b/src/shared/clang/clang_installation.pri
index acd555dd06..4629aedaab 100644
--- a/src/shared/clang/clang_installation.pri
+++ b/src/shared/clang/clang_installation.pri
@@ -153,11 +153,20 @@ LLVM_VERSION = $$extractVersion($$output)
!isEmpty(LLVM_VERSION) {
versionIsAtLeast($$LLVM_VERSION, 7, 0, 0): {
CLANGFORMAT_LIBS=-lclangFormat -lclangToolingInclusions -lclangToolingCore -lclangRewrite -lclangLex -lclangBasic
- win32:CLANGFORMAT_LIBS += -lversion
+ ALL_CLANG_LIBS=-lclangFormat -lclangToolingInclusions -lclangTooling -lclangToolingCore \
+ -lclangRewrite -lclangIndex -lclangFrontend -lclangParse -lclangSerialization \
+ -lclangSema -lclangEdit -lclangAnalysis -lclangDriver -lclangDynamicASTMatchers \
+ -lclangASTMatchers -lclangAST -lclangLex -lclangBasic
} else:versionIsAtLeast($$LLVM_VERSION, 6, 0, 0): {
CLANGFORMAT_LIBS=-lclangFormat -lclangToolingCore -lclangRewrite -lclangLex -lclangBasic
- win32:CLANGFORMAT_LIBS += -lversion
+ ALL_CLANG_LIBS=-lclangFormat -lclangTooling -lclangToolingCore \
+ -lclangRewrite -lclangIndex -lclangFrontend -lclangParse -lclangSerialization \
+ -lclangSema -lclangEdit -lclangAnalysis -lclangDriver -lclangDynamicASTMatchers \
+ -lclangASTMatchers -lclangAST -lclangLex -lclangBasic
}
+
+ win32:CLANGFORMAT_LIBS += -lversion
+ win32:ALL_CLANG_LIBS += -lversion
}
isEmpty(LLVM_VERSION) {
@@ -223,6 +232,7 @@ isEmpty(LLVM_VERSION) {
}
CLANGFORMAT_LIBS = -L$${LLVM_LIBDIR} $$CLANGFORMAT_LIBS $$LLVM_STATIC_LIBS
+ ALL_CLANG_LIBS = -L$${LLVM_LIBDIR} $$ALL_CLANG_LIBS $$CLANG_LIB $$LLVM_STATIC_LIBS
contains(QMAKE_DEFAULT_INCDIRS, $$LLVM_INCLUDEPATH): LLVM_INCLUDEPATH =