summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorjkobus <jaroslaw.kobus@digia.com>2014-07-09 12:37:47 +0200
committerJarek Kobus <jaroslaw.kobus@digia.com>2014-07-09 16:19:51 +0200
commitc9c4f05fee709cf6bf2089f03009d1b51e0b0b54 (patch)
tree62af6cf299f5e1a2cc6f53990af1ae54d8d56025 /src
parent89b8c9d523b567eb4c35093e112657f5642a4c46 (diff)
downloadqt-creator-c9c4f05fee709cf6bf2089f03009d1b51e0b0b54.tar.gz
Fix newline handling in diff editor
Task-number: QTCREATORBUG-12618 Change-Id: If2a30ff4efdc106f43e2ea77d2783ea797e92722 Reviewed-by: Orgad Shaneh <orgads@gmail.com>
Diffstat (limited to 'src')
-rw-r--r--src/plugins/diffeditor/diffeditorplugin.cpp147
-rw-r--r--src/plugins/diffeditor/diffutils.cpp73
-rw-r--r--src/plugins/diffeditor/unifieddiffeditorwidget.cpp13
3 files changed, 190 insertions, 43 deletions
diff --git a/src/plugins/diffeditor/diffeditorplugin.cpp b/src/plugins/diffeditor/diffeditorplugin.cpp
index 0d6ad83df0..699b4716c1 100644
--- a/src/plugins/diffeditor/diffeditorplugin.cpp
+++ b/src/plugins/diffeditor/diffeditorplugin.cpp
@@ -240,13 +240,26 @@ void DiffEditor::Internal::DiffEditorPlugin::testMakePatch_data()
rows << RowData(TextLineData(QLatin1String("ABCD")),
TextLineData(TextLineData::Separator));
rows << RowData(TextLineData(QLatin1String("EFGH")));
- rows << RowData(TextLineData(QLatin1String("")));
ChunkData chunk;
chunk.rows = rows;
QString patchText = header + QLatin1String("@@ -1,2 +1,1 @@\n"
"-ABCD\n"
" EFGH\n");
- QTest::newRow("Simple") << chunk
+ QTest::newRow("Simple not a last chunk") << chunk
+ << fileName
+ << fileName
+ << false
+ << patchText;
+
+ ///////////
+
+ // chunk the same here
+ patchText = header + QLatin1String("@@ -1,2 +1,1 @@\n"
+ "-ABCD\n"
+ " EFGH\n"
+ "\\ No newline at end of file\n");
+
+ QTest::newRow("Simple last chunk") << chunk
<< fileName
<< fileName
<< true
@@ -255,8 +268,7 @@ void DiffEditor::Internal::DiffEditorPlugin::testMakePatch_data()
///////////
rows.clear();
- rows << RowData(TextLineData(QLatin1String("ABCD")),
- TextLineData(QLatin1String("ABCD")));
+ rows << RowData(TextLineData(QLatin1String("ABCD")));
rows << RowData(TextLineData(QLatin1String("")),
TextLineData(TextLineData::Separator));
chunk.rows = rows;
@@ -265,7 +277,7 @@ void DiffEditor::Internal::DiffEditorPlugin::testMakePatch_data()
"+ABCD\n"
"\\ No newline at end of file\n");
- QTest::newRow("Last newline removed") << chunk
+ QTest::newRow("EOL in last line removed") << chunk
<< fileName
<< fileName
<< true
@@ -275,11 +287,10 @@ void DiffEditor::Internal::DiffEditorPlugin::testMakePatch_data()
// chunk the same here
patchText = header + QLatin1String("@@ -1,2 +1,1 @@\n"
- "-ABCD\n"
- "-\n"
- "+ABCD\n");
+ " ABCD\n"
+ "-\n");
- QTest::newRow("Not a last newline removed") << chunk
+ QTest::newRow("Last empty line removed") << chunk
<< fileName
<< fileName
<< false
@@ -288,8 +299,7 @@ void DiffEditor::Internal::DiffEditorPlugin::testMakePatch_data()
///////////
rows.clear();
- rows << RowData(TextLineData(QLatin1String("ABCD")),
- TextLineData(QLatin1String("ABCD")));
+ rows << RowData(TextLineData(QLatin1String("ABCD")));
rows << RowData(TextLineData(TextLineData::Separator),
TextLineData(QLatin1String("")));
chunk.rows = rows;
@@ -298,7 +308,7 @@ void DiffEditor::Internal::DiffEditorPlugin::testMakePatch_data()
"\\ No newline at end of file\n"
"+ABCD\n");
- QTest::newRow("Last newline added") << chunk
+ QTest::newRow("EOL to last line added") << chunk
<< fileName
<< fileName
<< true
@@ -308,11 +318,10 @@ void DiffEditor::Internal::DiffEditorPlugin::testMakePatch_data()
// chunk the same here
patchText = header + QLatin1String("@@ -1,1 +1,2 @@\n"
- "-ABCD\n"
- "+ABCD\n"
+ " ABCD\n"
"+\n");
- QTest::newRow("Not a last newline added") << chunk
+ QTest::newRow("Last empty line added") << chunk
<< fileName
<< fileName
<< false
@@ -323,7 +332,6 @@ void DiffEditor::Internal::DiffEditorPlugin::testMakePatch_data()
rows.clear();
rows << RowData(TextLineData(QLatin1String("ABCD")),
TextLineData(QLatin1String("EFGH")));
- rows << RowData(TextLineData(QLatin1String("")));
chunk.rows = rows;
patchText = header + QLatin1String("@@ -1,1 +1,1 @@\n"
"-ABCD\n"
@@ -332,12 +340,16 @@ void DiffEditor::Internal::DiffEditorPlugin::testMakePatch_data()
QTest::newRow("Last line with a newline modified") << chunk
<< fileName
<< fileName
- << true
+ << false
<< patchText;
///////////
- // chunk the same here
+ rows.clear();
+ rows << RowData(TextLineData(QLatin1String("ABCD")),
+ TextLineData(QLatin1String("EFGH")));
+ rows << RowData(TextLineData(QLatin1String("")));
+ chunk.rows = rows;
patchText = header + QLatin1String("@@ -1,2 +1,2 @@\n"
"-ABCD\n"
"+EFGH\n"
@@ -424,7 +436,35 @@ void DiffEditor::Internal::DiffEditorPlugin::testMakePatch()
QString result = DiffUtils::makePatch(sourceChunk, leftFileName, rightFileName, lastChunk);
- QCOMPARE(patchText, result);
+ QCOMPARE(result, patchText);
+
+ bool ok;
+ QList<FileData> resultList = DiffUtils::readPatch(result, false, &ok);
+
+ QVERIFY(ok);
+ QCOMPARE(resultList.count(), 1);
+ for (int i = 0; i < resultList.count(); i++) {
+ const FileData &resultFileData = resultList.at(i);
+ QCOMPARE(resultFileData.leftFileInfo.fileName, leftFileName);
+ QCOMPARE(resultFileData.rightFileInfo.fileName, rightFileName);
+ QCOMPARE(resultFileData.chunks.count(), 1);
+ for (int j = 0; j < resultFileData.chunks.count(); j++) {
+ const ChunkData &resultChunkData = resultFileData.chunks.at(j);
+ QCOMPARE(resultChunkData.leftStartingLineNumber, sourceChunk.leftStartingLineNumber);
+ QCOMPARE(resultChunkData.rightStartingLineNumber, sourceChunk.rightStartingLineNumber);
+ QCOMPARE(resultChunkData.contextChunk, sourceChunk.contextChunk);
+ QCOMPARE(resultChunkData.rows.count(), sourceChunk.rows.count());
+ for (int k = 0; k < sourceChunk.rows.count(); k++) {
+ const RowData &sourceRowData = sourceChunk.rows.at(k);
+ const RowData &resultRowData = resultChunkData.rows.at(k);
+ QCOMPARE(resultRowData.equal, sourceRowData.equal);
+ QCOMPARE(resultRowData.leftLine.text, sourceRowData.leftLine.text);
+ QCOMPARE(resultRowData.leftLine.textLineType, sourceRowData.leftLine.textLineType);
+ QCOMPARE(resultRowData.rightLine.text, sourceRowData.rightLine.text);
+ QCOMPARE(resultRowData.rightLine.textLineType, sourceRowData.rightLine.textLineType);
+ }
+ }
+ }
}
void DiffEditor::Internal::DiffEditorPlugin::testReadPatch_data()
@@ -614,11 +654,74 @@ void DiffEditor::Internal::DiffEditorPlugin::testReadPatch_data()
fileData8.rightFileInfo = DiffFileInfo(QLatin1String("file b.txt"));
fileData8.fileOperation = FileData::RenameFile;
- QList<FileData> fileDataList;
- fileDataList << fileData1 << fileData2 << fileData3 << fileData4 << fileData5 << fileData6 << fileData7 << fileData8;
+ QList<FileData> fileDataList1;
+ fileDataList1 << fileData1 << fileData2 << fileData3 << fileData4 << fileData5 << fileData6 << fileData7 << fileData8;
QTest::newRow("Git patch") << patch
- << fileDataList;
+ << fileDataList1;
+
+ //////////////
+
+ patch = QLatin1String("diff --git a/file foo.txt b/file foo.txt\n"
+ "index 1234567..9876543 100644\n"
+ "--- a/file foo.txt\n"
+ "+++ b/file foo.txt\n"
+ "@@ -50,4 +50,5 @@ void DiffEditor::ctor()\n"
+ " A\n"
+ " B\n"
+ " C\n"
+ "+\n");
+
+ fileData1.leftFileInfo = DiffFileInfo(QLatin1String("file foo.txt"), QLatin1String("1234567"));
+ fileData1.rightFileInfo = DiffFileInfo(QLatin1String("file foo.txt"), QLatin1String("9876543"));
+ fileData1.fileOperation = FileData::ChangeFile;
+ chunkData1.leftStartingLineNumber = 49;
+ chunkData1.rightStartingLineNumber = 49;
+ rows1.clear();
+ rows1.append(RowData(TextLineData(QLatin1String("A"))));
+ rows1.append(RowData(TextLineData(QLatin1String("B"))));
+ rows1.append(RowData(TextLineData(QLatin1String("C"))));
+ rows1.append(RowData(TextLineData(TextLineData::Separator),
+ TextLineData(QLatin1String(""))));
+ chunkData1.rows = rows1;
+ fileData1.chunks.clear();
+ fileData1.chunks.append(chunkData1);
+
+ QList<FileData> fileDataList2;
+ fileDataList2 << fileData1;
+
+ QTest::newRow("Added line") << patch
+ << fileDataList2;
+
+ //////////////
+
+ patch = QLatin1String("diff --git a/file foo.txt b/file foo.txt\n"
+ "index 1234567..9876543 100644\n"
+ "--- a/file foo.txt\n"
+ "+++ b/file foo.txt\n"
+ "@@ -1,1 +1,1 @@\n"
+ "-ABCD\n"
+ "\\ No newline at end of file\n"
+ "+ABCD\n");
+
+ fileData1.leftFileInfo = DiffFileInfo(QLatin1String("file foo.txt"), QLatin1String("1234567"));
+ fileData1.rightFileInfo = DiffFileInfo(QLatin1String("file foo.txt"), QLatin1String("9876543"));
+ fileData1.fileOperation = FileData::ChangeFile;
+ chunkData1.leftStartingLineNumber = 0;
+ chunkData1.rightStartingLineNumber = 0;
+ rows1.clear();
+ rows1.append(RowData(TextLineData(QLatin1String("ABCD"))));
+ rows1.append(RowData(TextLineData(TextLineData::Separator),
+ TextLineData(QLatin1String(""))));
+ chunkData1.rows = rows1;
+ fileData1.chunks.clear();
+ fileData1.chunks.append(chunkData1);
+
+ QList<FileData> fileDataList3;
+ fileDataList3 << fileData1;
+
+ QTest::newRow("Last newline added to a line without newline") << patch
+ << fileDataList3;
}
void DiffEditor::Internal::DiffEditorPlugin::testReadPatch()
diff --git a/src/plugins/diffeditor/diffutils.cpp b/src/plugins/diffeditor/diffutils.cpp
index 18725363fb..f975462c47 100644
--- a/src/plugins/diffeditor/diffutils.cpp
+++ b/src/plugins/diffeditor/diffutils.cpp
@@ -131,15 +131,23 @@ ChunkData DiffUtils::calculateOriginalData(const QList<Diff> &leftDiffList,
: Diff(Diff::Equal);
if (leftDiff.command == Diff::Delete) {
+ if (j == rightDiffList.count() && lastLineEqual && leftDiff.text.startsWith(QLatin1Char('\n')))
+ equalLines.insert(leftLineNumber, rightLineNumber);
// process delete
handleDifference(leftDiff.text, &leftLines, &leftLineNumber);
lastLineEqual = lastLinesEqual(leftLines, rightLines);
+ if (j == rightDiffList.count())
+ lastLineEqual = false;
i++;
}
if (rightDiff.command == Diff::Insert) {
+ if (i == leftDiffList.count() && lastLineEqual && rightDiff.text.startsWith(QLatin1Char('\n')))
+ equalLines.insert(leftLineNumber, rightLineNumber);
// process insert
handleDifference(rightDiff.text, &rightLines, &rightLineNumber);
lastLineEqual = lastLinesEqual(leftLines, rightLines);
+ if (i == leftDiffList.count())
+ lastLineEqual = false;
j++;
}
if (leftDiff.command == Diff::Equal && rightDiff.command == Diff::Equal) {
@@ -262,6 +270,7 @@ FileData DiffUtils::calculateContextData(const ChunkData &originalData,
FileData fileData;
fileData.contextChunksIncluded = true;
+ fileData.lastChunkAtTheEndOfFile = true;
QMap<int, bool> hiddenRows;
int i = 0;
@@ -353,13 +362,24 @@ QString DiffUtils::makePatch(const ChunkData &chunkData,
int rightLineCount = 0;
QList<TextLineData> leftBuffer, rightBuffer;
+ int lastEqualRow = -1;
+ if (lastChunk) {
+ for (int i = chunkData.rows.count(); i > 0; i--) {
+ if (chunkData.rows.at(i - 1).equal) {
+ if (i != chunkData.rows.count())
+ lastEqualRow = i - 1;
+ break;
+ }
+ }
+ }
+
for (int i = 0; i <= chunkData.rows.count(); i++) {
const RowData &rowData = i < chunkData.rows.count()
? chunkData.rows.at(i)
: RowData(TextLineData(TextLineData::Separator)); // dummy,
// ensure we process buffers to the end.
// rowData will be equal
- if (rowData.equal) {
+ if (rowData.equal && i != lastEqualRow) {
if (leftBuffer.count()) {
for (int j = 0; j < leftBuffer.count(); j++) {
const QString line = makePatchLine(QLatin1Char('-'),
@@ -554,11 +574,15 @@ static QList<RowData> readLines(const QString &patch,
}
}
- if (i < lines.count()
+ if (i < lines.count() // we broke before
+ // or we have noNewLine in some equal line and in either delete or insert line
|| (noNewLineInEqual >= 0 && (noNewLineInDelete >= 0 || noNewLineInInsert >= 0))
+ // or we have noNewLine in not the last equal line
|| (noNewLineInEqual >= 0 && noNewLineInEqual != lastEqual)
- || (noNewLineInDelete >= 0 && noNewLineInDelete != lastDelete)
- || (noNewLineInInsert >= 0 && noNewLineInInsert != lastInsert)) {
+ // or we have noNewLine in not the last delete line or there is a equal line after the noNewLine for delete
+ || (noNewLineInDelete >= 0 && (noNewLineInDelete != lastDelete || lastEqual > lastDelete))
+ // or we have noNewLine in not the last insert line or there is a equal line after the noNewLine for insert
+ || (noNewLineInInsert >= 0 && (noNewLineInInsert != lastInsert || lastEqual > lastInsert))) {
if (ok)
*ok = false;
return QList<RowData>();
@@ -577,26 +601,35 @@ static QList<RowData> readLines(const QString &patch,
removeNewLineFromLastDelete = true;
if (noNewLineInInsert >= 0)
removeNewLineFromLastInsert = true;
- } else if (lastEqual > lastDelete && lastEqual > lastInsert) {
- removeNewLineFromLastEqual = true;
- } else if (lastDelete > lastEqual && lastDelete > lastInsert) {
- if (lastInsert > lastEqual) {
- removeNewLineFromLastDelete = true;
- removeNewLineFromLastInsert = true;
- } else if (lastEqual > lastInsert) {
- removeNewLineFromLastEqual = true;
- prependNewLineAfterLastEqual = true;
- }
- } else if (lastInsert > lastEqual && lastInsert > lastDelete) {
- if (lastDelete > lastEqual) {
- removeNewLineFromLastDelete = true;
- removeNewLineFromLastInsert = true;
- } else if (lastEqual > lastDelete) {
+ } else {
+ if (noNewLineInEqual >= 0) {
removeNewLineFromLastEqual = true;
- prependNewLineAfterLastEqual = true;
+ } else if (lastChunk) {
+ if (lastEqual > lastDelete && lastEqual > lastInsert) {
+ removeNewLineFromLastEqual = true;
+ } else if (lastDelete > lastEqual && lastDelete > lastInsert) {
+ if (lastInsert > lastEqual) {
+ removeNewLineFromLastDelete = true;
+ removeNewLineFromLastInsert = true;
+ } else if (lastEqual > lastInsert) {
+ removeNewLineFromLastEqual = true;
+ removeNewLineFromLastDelete = true;
+ prependNewLineAfterLastEqual = true;
+ }
+ } else if (lastInsert > lastEqual && lastInsert > lastDelete) {
+ if (lastDelete > lastEqual) {
+ removeNewLineFromLastDelete = true;
+ removeNewLineFromLastInsert = true;
+ } else if (lastEqual > lastDelete) {
+ removeNewLineFromLastEqual = true;
+ removeNewLineFromLastInsert = true;
+ prependNewLineAfterLastEqual = true;
+ }
+ }
}
}
+
if (removeNewLineFromLastEqual) {
Diff &diff = diffList[lastEqual];
diff.text = diff.text.left(diff.text.count() - 1);
diff --git a/src/plugins/diffeditor/unifieddiffeditorwidget.cpp b/src/plugins/diffeditor/unifieddiffeditorwidget.cpp
index 87001b3fe6..5858fe91ff 100644
--- a/src/plugins/diffeditor/unifieddiffeditorwidget.cpp
+++ b/src/plugins/diffeditor/unifieddiffeditorwidget.cpp
@@ -478,13 +478,24 @@ QString UnifiedDiffEditorWidget::showChunk(const ChunkData &chunkData,
(*selections)[*blockNumber].append(DiffSelection(&m_chunkLineFormat));
+ int lastEqualRow = -1;
+ if (lastChunk) {
+ for (int i = chunkData.rows.count(); i > 0; i--) {
+ if (chunkData.rows.at(i - 1).equal) {
+ if (i != chunkData.rows.count())
+ lastEqualRow = i - 1;
+ break;
+ }
+ }
+ }
+
for (int i = 0; i <= chunkData.rows.count(); i++) {
const RowData &rowData = i < chunkData.rows.count()
? chunkData.rows.at(i)
: RowData(TextLineData(TextLineData::Separator)); // dummy,
// ensure we process buffers to the end.
// rowData will be equal
- if (rowData.equal) {
+ if (rowData.equal && i != lastEqualRow) {
if (leftBuffer.count()) {
for (int j = 0; j < leftBuffer.count(); j++) {
const TextLineData &lineData = leftBuffer.at(j);