KCoreAddons

kfuzzymatcher.h
1 /*
2  This file is part of the KDE libraries
3 
4  SPDX-FileCopyrightText: 2017 Forrest Smith <[email protected]>
5  SPDX-FileCopyrightText: 2021 Waqar Ahmed <[email protected]>
6 
7  SPDX-License-Identifier: LGPL-2.0-or-later
8 */
9 #ifndef KFUZZYMATCHER_H
10 #define KFUZZYMATCHER_H
11 
12 #include <kcoreaddons_export.h>
13 
14 class QString;
15 class QStringView;
16 
17 /**
18  * This namespace contains functions for fuzzy matching a list of strings
19  * against a pattern.
20  *
21  * This code is ported to Qt from lib_fts:
22  * https://github.com/forrestthewoods/lib_fts
23  * which tries to replicate SublimeText like fuzzy matching.
24  *
25  * @note
26  * All character matches will happen sequentially. That means that this function is not
27  * typo tolerant i.e., "gti" will not match "git", but "gt" will. All methods in here are
28  * stateless i.e., the input string will not be modified. Also note that strings in all the
29  * functions in this namespace will be matched case-insensitively.
30  *
31  * Limitations:
32  * - Currently this will match only strings with length < 256 correctly. This is because we
33  * intend on matching a pattern against words / short strings and not paragraphs.
34  * - No more than 256 matches will happen.
35  *
36  * If you are using this with @c QSortFilterProxyModel, you need to override both
37  * @c QSortFilterProxyModel::lessThan and @c QSortFilterProxyModel::filterAcceptsRow.
38  * A simple example:
39  *
40  * \code
41  bool filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const override
42  {
43  int score = 0;
44  const auto idx = sourceModel()->index(sourceRow, 0, sourceParent);
45  const auto actionName = idx.data().toString().splitRef(QLatin1Char(':')).at(1);
46  const bool res = kfts::fuzzy_match_sequential(m_pattern, actionName, score);
47  // store the score in the source model
48  sourceModel()->setData(idx, score, ScoreRole);
49  return res;
50  }
51 
52  bool lessThan(const QModelIndex &sourceLeft, const QModelIndex &sourceRight) const override
53  {
54  // use the score here to sort
55  const int l = sourceLeft.data(ScoreRole).toInt();
56  const int r = sourceRight.data(ScoreRole).toInt();
57  return l < r;
58  }
59  * \endcode
60  *
61  * Additionally you must not use @c invalidateFilter() if you go with the above approach. Instead
62  * use @c beginResetModel()/@c endResetModel():
63  *
64  * \code
65  * Q_SLOT void setFilterString(const QString &string)
66  {
67  beginResetModel();
68  m_pattern = string;
69  endResetModel();
70  }
71  * \endcode
72  *
73  * @short Namespace for fuzzy matching of strings
74  * @author Waqar Ahmed <[email protected]>
75  */
76 namespace KFuzzyMatcher
77 {
78 /**
79  * @brief The result of a fuzzy match
80  */
81 struct KCOREADDONS_EXPORT Result {
82  /**
83  * Score of this match. This can be negative.if matched is @c false
84  * then the score will be zero.
85  */
86  int score = 0;
87  /** @c true if match was successful */
88  bool matched = false;
89 };
90 
91 /**
92  * @brief Simple fuzzy matching of chars in @p pattern with chars in @p str
93  * sequentially. If there is a match, it will return true and false otherwise.
94  * There is no scoring. You should use this if score is not important for you
95  * and only matching is important.
96  *
97  * If @p pattern is empty, the function will return @c true
98  *
99  * @param pattern to search for. For e.g., text entered by a user to filter a
100  * list
101  * @param str the current string from your list of strings
102  * @return @c true on sucessful match
103  *
104  * @since 5.79
105  */
106 KCOREADDONS_EXPORT bool matchSimple(QStringView pattern, QStringView str);
107 
108 /**
109  * @brief This is the main function which does scored fuzzy matching.
110  *
111  * The return value of this function contains Result#score which should be used to
112  * sort the results. Without sorting of the results this function won't very effective.
113  *
114  * If @p pattern is empty, the function will return @c true
115  *
116  * @param pattern to search for. For e.g., text entered by a user to filter a
117  * list or model
118  * @param str the current string from your list of strings
119  * @return A Result type with score of this match and whether the match was
120  * successful. If there is no match, score is zero. If the match is successful,
121  * score must be used to sort the results.
122  *
123  * @since 5.79
124  */
125 KCOREADDONS_EXPORT Result match(QStringView pattern, QStringView str);
126 
127 } // namespace KFuzzyMatcher
128 
129 #endif // KFUZZYMATCHER_H
The result of a fuzzy match.
Definition: kfuzzymatcher.h:81
KCOREADDONS_EXPORT bool matchSimple(QStringView pattern, QStringView str)
Simple fuzzy matching of chars in pattern with chars in str sequentially.
This namespace contains functions for fuzzy matching a list of strings against a pattern.
Definition: kfuzzymatcher.h:76
KCOREADDONS_EXPORT Result match(QStringView pattern, QStringView str)
This is the main function which does scored fuzzy matching.
This file is part of the KDE documentation.
Documentation copyright © 1996-2021 The KDE developers.
Generated on Sun Apr 18 2021 23:02:02 by doxygen 1.8.11 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.