diff --git a/debian/changelog b/debian/changelog index 370cca3..067b874 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,10 @@ +util-dfm (1.3.59) unstable; urgency=medium + + * fix: improve symlink handling in filename search + * feat: add configurable keyword positioning in search results + + -- Zhang Sheng Wed, 17 Jun 2026 15:22:52 +0800 + util-dfm (1.3.58) unstable; urgency=medium * fix: simplify file timestamp attribute handling diff --git a/include/dfm-search/dfm-search/contentretriever.h b/include/dfm-search/dfm-search/contentretriever.h index 673f38e..17f6338 100644 --- a/include/dfm-search/dfm-search/contentretriever.h +++ b/include/dfm-search/dfm-search/contentretriever.h @@ -18,8 +18,9 @@ DFM_SEARCH_BEGIN_NS */ struct HighlightOptions { - int maxPreviewLength = 200; ///< Maximum snippet length in characters - bool enableHtml = false; ///< Wrap matched keywords with tags + int maxPreviewLength = 200; ///< Maximum snippet length in characters + int positioningMaxLength = 30; ///< Keyword positioning window size (min 30) + bool enableHtml = false; ///< Wrap matched keywords with tags }; /** diff --git a/src/dfm-search/dfm-search-lib/utils/contenthighlighter.cpp b/src/dfm-search/dfm-search-lib/utils/contenthighlighter.cpp index cc95dd1..e6f1c70 100644 --- a/src/dfm-search/dfm-search-lib/utils/contenthighlighter.cpp +++ b/src/dfm-search/dfm-search-lib/utils/contenthighlighter.cpp @@ -155,7 +155,7 @@ KeywordMatch findFirstKeywordMatch(const QString &content, const QStringList &ke } } // namespace -QString customHighlight(const QStringList &keywords, const QString &content, int maxLength, bool enableHtml) +QString customHighlight(const QStringList &keywords, const QString &content, int maxLength, bool enableHtml, int positioningMaxLength) { if (content.isEmpty() || keywords.isEmpty()) { return QString(); @@ -191,13 +191,13 @@ QString customHighlight(const QStringList &keywords, const QString &content, int return match.keyword; // Return the keyword as is (original behavior) } - // This is the "30 characters" from the requirement, used for positioning the keyword. - const int positioningMaxLength = 30; + // Enforce minimum of 30 for the positioning window + const int effectivePositioningLength = qMax(30, positioningMaxLength); // 1. Calculate the optimal start position. // This start position is determined based on making the keyword visible - // and well-positioned within a `positioningMaxLength` (e.g., 80 char) window. - int optimalStart = findOptimalStartPosition(content, match.position, positioningMaxLength); + // and well-positioned within the positioning window. + int optimalStart = findOptimalStartPosition(content, match.position, effectivePositioningLength); // 2. Calculate the optimal end position. // This uses the `optimalStart` calculated above and extends the snippet diff --git a/src/dfm-search/dfm-search-lib/utils/contenthighlighter.h b/src/dfm-search/dfm-search-lib/utils/contenthighlighter.h index e926fd6..fbaffdd 100644 --- a/src/dfm-search/dfm-search-lib/utils/contenthighlighter.h +++ b/src/dfm-search/dfm-search-lib/utils/contenthighlighter.h @@ -33,11 +33,12 @@ namespace ContentHighlighter { * * @param keywords A list of search keywords (supports wildcards *, ?). * @param content The original document content to be searched. - * @param maxLength The maximum length of the returned snippet (used when no line breaks are present). - * @param enableHtml Whether to wrap matched keywords with tags for highlighting. + * @param maxLength The maximum length of the returned snippet (used when no line breaks are present). + * @param enableHtml Whether to wrap matched keywords with tags for highlighting. + * @param positioningMaxLength Keyword positioning window size for finding the optimal snippet start/end (min 30). * @return A snippet of content with matched keywords highlighted, or an empty string if no match is found. */ -QString customHighlight(const QStringList &keywords, const QString &content, int maxLength, bool enableHtml); +QString customHighlight(const QStringList &keywords, const QString &content, int maxLength, bool enableHtml, int positioningMaxLength = 30); } // namespace ContentHighlighter diff --git a/src/dfm-search/dfm-search-lib/utils/contentretriever.cpp b/src/dfm-search/dfm-search-lib/utils/contentretriever.cpp index 8dbc7c4..c86225c 100644 --- a/src/dfm-search/dfm-search-lib/utils/contentretriever.cpp +++ b/src/dfm-search/dfm-search-lib/utils/contentretriever.cpp @@ -219,7 +219,8 @@ QString ContentRetriever::fetchHighlight(const QString &path, } return ContentHighlighter::customHighlight( - keywords, content, options.maxPreviewLength, options.enableHtml); + keywords, content, options.maxPreviewLength, options.enableHtml, + options.positioningMaxLength); } catch (const LuceneException &e) { qWarning() << "ContentRetriever: error fetching highlight for" << path << QString::fromStdWString(e.getError()); @@ -260,7 +261,8 @@ QMap ContentRetriever::fetchHighlights(const QStringList &path } results.insert(path, ContentHighlighter::customHighlight( - keywords, content, options.maxPreviewLength, options.enableHtml)); + keywords, content, options.maxPreviewLength, options.enableHtml, + options.positioningMaxLength)); } catch (const LuceneException &e) { qWarning() << "ContentRetriever: error for" << path << QString::fromStdWString(e.getError());