qmlls: Fix TextSynchronization
The offset from a given range was incorrectly calculated in findBlockByNumber because textblocks that are used to obtain that position were mistakenly ignoring the newline character. This were leading us to setting a different text than what we actually typed. Add an extra text block if the text ends with \n. Add a manual test but exclude it from tst_qmlformat as it is not a valid qml document. Fixes: QTBUG-113725 Change-Id: Ifb1b4121fd8af46df7627d986303ae67e170e50c Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
This commit is contained in:
parent
dc30e3859f
commit
7a4175ff60
|
@ -68,22 +68,30 @@ void TextDocument::setPlainText(const QString &text)
|
||||||
m_content = text;
|
m_content = text;
|
||||||
m_blocks.clear();
|
m_blocks.clear();
|
||||||
|
|
||||||
int blockStart = 0;
|
const auto appendToBlocks = [this](int blockNumber, int start, int length) {
|
||||||
int blockNumber = 0;
|
|
||||||
while (blockStart < text.size()) {
|
|
||||||
Block block;
|
Block block;
|
||||||
block.textBlock.setBlockNumber(blockNumber++);
|
block.textBlock.setBlockNumber(blockNumber);
|
||||||
block.textBlock.setPosition(blockStart);
|
block.textBlock.setPosition(start);
|
||||||
block.textBlock.setDocument(this);
|
block.textBlock.setDocument(this);
|
||||||
|
block.textBlock.setLength(length);
|
||||||
|
m_blocks.append(block);
|
||||||
|
};
|
||||||
|
|
||||||
|
int blockStart = 0;
|
||||||
|
int blockNumber = -1;
|
||||||
|
while (blockStart < text.size()) {
|
||||||
int blockEnd = text.indexOf(u'\n', blockStart) + 1;
|
int blockEnd = text.indexOf(u'\n', blockStart) + 1;
|
||||||
if (blockEnd == 0)
|
if (blockEnd == 0)
|
||||||
blockEnd = text.size();
|
blockEnd = text.size();
|
||||||
|
appendToBlocks(++blockNumber, blockStart, blockEnd - blockStart);
|
||||||
block.textBlock.setLength(blockEnd - blockStart);
|
|
||||||
m_blocks.append(block);
|
|
||||||
blockStart = blockEnd;
|
blockStart = blockEnd;
|
||||||
}
|
}
|
||||||
|
// Add an empty block if the text ends with \n. This is required for retrieving
|
||||||
|
// the actual line of the text editor if requested, for example, in findBlockByNumber.
|
||||||
|
// Consider a case with text aa\nbb\n\n. You are on 4th line of the text editor and even
|
||||||
|
// if it is an empty line, we introduce a text block for it to maybe use later.
|
||||||
|
if (text.endsWith(u'\n'))
|
||||||
|
appendToBlocks(++blockNumber, blockStart, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool TextDocument::isModified() const
|
bool TextDocument::isModified() const
|
||||||
|
|
|
@ -87,6 +87,7 @@ void TestQmlformat::initTestCase()
|
||||||
m_excludedDirs << "doc/src/snippets/qtquick1/qtbinding";
|
m_excludedDirs << "doc/src/snippets/qtquick1/qtbinding";
|
||||||
m_excludedDirs << "doc/src/snippets/qtquick1/imports";
|
m_excludedDirs << "doc/src/snippets/qtquick1/imports";
|
||||||
m_excludedDirs << "tests/manual/v4";
|
m_excludedDirs << "tests/manual/v4";
|
||||||
|
m_excludedDirs << "tests/manual/qmllsformatter";
|
||||||
m_excludedDirs << "tests/auto/qml/ecmascripttests";
|
m_excludedDirs << "tests/auto/qml/ecmascripttests";
|
||||||
m_excludedDirs << "tests/auto/qml/qmllint";
|
m_excludedDirs << "tests/auto/qml/qmllint";
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,45 @@
|
||||||
|
// Copyright (C) 2023 The Qt Company Ltd.
|
||||||
|
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
|
||||||
|
|
||||||
|
// Start Test
|
||||||
|
// Open that test.qml file in a text editor that has a client for qmlls
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
// Test Case - 1
|
||||||
|
// Type the following line manually
|
||||||
|
|
||||||
|
import QtQml
|
||||||
|
|
||||||
|
Window {
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// Then, execute "Format Document" in the text editor
|
||||||
|
|
||||||
|
// Expected Result
|
||||||
|
import QtQml
|
||||||
|
|
||||||
|
Window {
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
// Test Case - 2
|
||||||
|
// Type the following line manually
|
||||||
|
|
||||||
|
import QtQml
|
||||||
|
|
||||||
|
Window {
|
||||||
|
aa a: {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Then, execute "Format Document" in the text editor
|
||||||
|
|
||||||
|
// Expected Result
|
||||||
|
import QtQml
|
||||||
|
|
||||||
|
Window {
|
||||||
|
aa: {
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue