diff --git a/gui/previewgeneratorplaintext.cpp b/gui/previewgeneratorplaintext.cpp index c63f8ea..eb86852 100644 --- a/gui/previewgeneratorplaintext.cpp +++ b/gui/previewgeneratorplaintext.cpp @@ -1,4 +1,5 @@ #include +#include #include "previewgeneratorplaintext.h" #include "previewresultplaintext.h" @@ -74,9 +75,18 @@ QString PreviewGeneratorPlainText::generatePreviewText(QString content, RenderCo return header + resulText.replace("\n", "
").mid(0, 1000); } +struct Snippet +{ + /* Contains each line number and line of the snippet*/ + QString snippetText; + + /* How many times a word occurs in the snippetText */ + QHash wordCountMap; +}; + QString PreviewGeneratorPlainText::generateLineBasedPreviewText(QTextStream &in, RenderConfig config, QString fileName) { - QString resultText; + QVector snippets; const unsigned int contextLinesCount = 2; LimitQueue queue(contextLinesCount); QString currentLine; @@ -85,38 +95,58 @@ QString PreviewGeneratorPlainText::generateLineBasedPreviewText(QTextStream &in, /* How many lines to read after a line with a match (like grep -A ) */ int justReadLinesCount = -1; - auto appendLine = [&resultText](int lineNumber, QString &line) - { resultText.append(QString("%1%2
").arg(lineNumber).arg(line)); }; + struct Snippet currentSnippet; - QHash countmap; - QString header = "" + fileName + " "; + auto appendLine = [¤tSnippet, &config](int lineNumber, QString &line) + { + int foundWordsCount = 0; + for(QString &word : config.wordsToHighlight) + { + QRegularExpression searchRegex("\\b" + word + "\\b"); + if(line.contains(searchRegex)) + { + currentSnippet.wordCountMap[word] = currentSnippet.wordCountMap.value(word, 0) + 1; + line.replace(searchRegex, "" + word + ""); + ++foundWordsCount; + } + } + currentSnippet.snippetText.append(QString("%1%2
").arg(lineNumber).arg(line)); + return foundWordsCount; + }; - unsigned int snippetsCount = 0; unsigned int lineCount = 0; - while(in.readLineInto(¤tLine) && snippetsCount < MAX_SNIPPETS) + while(in.readLineInto(¤tLine)) { ++lineCount; bool matched = false; if(justReadLinesCount > 0) { - appendLine(lineCount, currentLine); - --justReadLinesCount; + + int result = appendLine(lineCount, currentLine); + if(justReadLinesCount == 1 && result > 0) + { + justReadLinesCount = contextLinesCount; + } + else + { + --justReadLinesCount; + } + continue; } if(justReadLinesCount == 0) { - resultText += "---
"; + currentSnippet.snippetText += "---
"; justReadLinesCount = -1; - ++snippetsCount; + snippets.append(currentSnippet); + currentSnippet = {}; } for(QString &word : config.wordsToHighlight) { - if(currentLine.contains(word, Qt::CaseInsensitive)) + if(currentLine.contains(QRegularExpression("\\b" + word + "\\b"))) { - countmap[word] = countmap.value(word, 0) + 1; matched = true; - currentLine.replace(word, "" + word + "", - Qt::CaseInsensitive); + break; } } if(matched) @@ -125,7 +155,6 @@ QString PreviewGeneratorPlainText::generateLineBasedPreviewText(QTextStream &in, { int queuedLineCount = lineCount - queue.size(); QString queuedLine = queue.dequeue(); - appendLine(queuedLineCount, queuedLine); } appendLine(lineCount, currentLine); @@ -137,13 +166,77 @@ QString PreviewGeneratorPlainText::generateLineBasedPreviewText(QTextStream &in, } } + if(!currentSnippet.snippetText.isEmpty()) + { + currentSnippet.snippetText += "---
"; + snippets.append(currentSnippet); + } + + std::sort(snippets.begin(), snippets.end(), + [](Snippet &a, Snippet &b) + { + int differentWordsA = 0; + int totalWordsA = 0; + int differentWordsB = 0; + int totalWordsB = 0; + for(int count : a.wordCountMap.values()) + { + if(count > 0) + { + ++differentWordsA; + } + totalWordsA += count; + } + for(int count : b.wordCountMap.values()) + { + if(count > 0) + { + ++differentWordsB; + } + totalWordsB += count; + } + + if(differentWordsA > differentWordsB) + { + return true; + } + if(differentWordsA == differentWordsB) + { + return totalWordsA > totalWordsB; + } + return false; + }); + + QString resultText = ""; + + unsigned int snippetsCount = 0; + + QString header = "" + fileName + " "; + + QHash totalWordCountMap; + bool isTruncated = false; + for(Snippet &snippet : snippets) + { + if(snippetsCount++ < MAX_SNIPPETS) + { + resultText += snippet.snippetText; + } + else + { + isTruncated = true; + } + for(auto it = snippet.wordCountMap.keyValueBegin(); it != snippet.wordCountMap.keyValueEnd(); it++) + { + totalWordCountMap[it->first] = totalWordCountMap.value(it->first, 0) + it->second; + } + } + if(isTruncated) + { + header += "(truncated) "; + } for(QString &word : config.wordsToHighlight) { - header += word + ": " + QString::number(countmap[word]) + " "; - } - if(snippetsCount == MAX_SNIPPETS) - { - header += "(truncated)"; + header += word + ": " + QString::number(totalWordCountMap[word]) + " "; } header += "
";