ClangFormat: Format edited chunks of file on save

The similar implementation to the one in Beautifier plugin
with the difference that the clangformat indenter logic is used
and only modified chunks are formatted.

That means that all code which was not touched will stay in the
initial condition.

Change-Id: I47b11eb99852454ed0031ef6cfc6dbed1ecd390d
Reviewed-by: Leena Miettinen <riitta-leena.miettinen@qt.io>
Reviewed-by: Marco Bubke <marco.bubke@qt.io>
This commit is contained in:
Ivan Donchevskii
2019-01-28 12:25:36 +01:00
parent 536b733f29
commit 5792291520
10 changed files with 85 additions and 1 deletions

View File

@@ -44,6 +44,7 @@
#include <projectexplorer/session.h>
#include <texteditor/icodestylepreferencesfactory.h>
#include <texteditor/textdocumentlayout.h>
#include <texteditor/texteditorsettings.h>
#include <coreplugin/editormanager/editormanager.h>
@@ -447,5 +448,47 @@ TextEditor::TabSettings CppEditorDocument::tabSettings() const
return indenter()->tabSettings().value_or(TextEditor::TextDocument::tabSettings());
}
static int formatRange(QTextDocument *doc,
TextEditor::Indenter *indenter,
std::pair<int, int> editedRange,
const TextEditor::TabSettings &tabSettings)
{
QTextCursor cursor(doc);
cursor.setPosition(editedRange.first);
cursor.setPosition(editedRange.second, QTextCursor::KeepAnchor);
const int oldBlockCount = doc->blockCount();
indenter->format(cursor, tabSettings);
return doc->blockCount() - oldBlockCount;
}
bool CppEditorDocument::save(QString *errorString, const QString &fileName, bool autoSave)
{
if (indenter()->formatOnSave()) {
auto *layout = qobject_cast<TextEditor::TextDocumentLayout *>(document()->documentLayout());
const int documentRevision = layout->lastSaveRevision;
std::pair<int, int> editedRange;
for (int i = 0; i < document()->blockCount(); ++i) {
const QTextBlock block = document()->findBlockByNumber(i);
if (block.revision() == documentRevision) {
if (editedRange.first != -1)
i += formatRange(document(), indenter(), editedRange, tabSettings());
editedRange = std::make_pair(-1, -1);
continue;
}
// block.revision() != documentRevision
if (editedRange.first == -1)
editedRange.first = block.position();
editedRange.second = block.position() + block.length();
}
if (editedRange.first != -1)
formatRange(document(), indenter(), editedRange, tabSettings());
}
return TextEditor::TextDocument::save(errorString, fileName, autoSave);
}
} // namespace Internal
} // namespace CppEditor