Skip to content

Commit ef36b20

Browse files
committed
fuzzy suggetion in auto complete
update screencast
1 parent 640ec73 commit ef36b20

File tree

8 files changed

+107
-9
lines changed

8 files changed

+107
-9
lines changed

Display/CMainWindow.cpp

Lines changed: 30 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -218,6 +218,7 @@ bTagBuildInProgress_(false)
218218
bool bSymbolSearchCaseSensitive;
219219
bool bSymbolSearchRegularExpression;
220220
bool bLiveSearch;
221+
bool bFuzzyAutoComplete;
221222

222223
bProjectAndGroupFilterCaseSensitive = confManager_->getAppSettingValue("ProjectAndGroupFilterCaseSensitive", false).toBool();
223224
if (bProjectAndGroupFilterCaseSensitive) {
@@ -306,6 +307,14 @@ bTagBuildInProgress_(false)
306307
actionLiveSearch->setChecked(false);
307308
}
308309

310+
// fuzzy auto complete
311+
bFuzzyAutoComplete = confManager_->getAppSettingValue("FuzzyAutoComplete", true).toBool();
312+
if (bFuzzyAutoComplete) {
313+
actionFuzzyAutoComplete->setChecked(true);
314+
} else {
315+
actionFuzzyAutoComplete->setChecked(false);
316+
}
317+
309318
createActions();
310319
}
311320

@@ -1189,10 +1198,17 @@ void CMainWindow::on_actionAlways_on_top_toggled()
11891198
on_actionTransparent_toggled(); // still transparency
11901199
}
11911200

1192-
void CMainWindow::on_actionLiveSearch_toggled()
1201+
void CMainWindow::on_actionFuzzyAutoComplete_toggled()
11931202
{
1194-
qDebug() << "on_actionLiveSearch_toggled IN";
1203+
if (actionFuzzyAutoComplete->isChecked()) {
1204+
confManager_->setAppSettingValue("FuzzyAutoComplete", true);
1205+
} else {
1206+
confManager_->setAppSettingValue("FuzzyAutoComplete", false);
1207+
}
1208+
}
11951209

1210+
void CMainWindow::on_actionLiveSearch_toggled()
1211+
{
11961212
if (actionLiveSearch->isChecked()) {
11971213
confManager_->setAppSettingValue("LiveSearch", true);
11981214
} else {
@@ -1564,7 +1580,14 @@ void CMainWindow::searchLineEditChanged()
15641580

15651581
QStringList tagList;
15661582
QMap<int, QString> tagMap;
1567-
tagger_.getMatchedTags(search_lineEdit->text(), tagMap, caseSensitivity);
1583+
1584+
bool bFuzzyAutoComplete = confManager_->getAppSettingValue("FuzzyAutoComplete", true).toBool();
1585+
1586+
if (bFuzzyAutoComplete) {
1587+
tagger_.getFuzzyMatchedTags(search_lineEdit->text(), tagMap, caseSensitivity);
1588+
} else {
1589+
tagger_.getMatchedTags(search_lineEdit->text(), tagMap, caseSensitivity);
1590+
}
15681591

15691592
for (auto tag: tagMap) {
15701593
tagList.push_back(tag);
@@ -1577,6 +1600,10 @@ void CMainWindow::searchLineEditChanged()
15771600
completer_.setCaseSensitivity(caseSensitivity);
15781601
completer_.setFilterMode(Qt::MatchContains);
15791602

1603+
if (bFuzzyAutoComplete) {
1604+
completer_.setCompletionMode(QCompleter::UnfilteredPopupCompletion);
1605+
}
1606+
15801607
search_lineEdit->setCompleter(&completer_);
15811608

15821609
bool bLiveSearch = confManager_->getAppSettingValue("LiveSearch", true).toBool();

Display/CMainWindow.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -133,6 +133,7 @@ private slots:
133133
void on_nextSymbolButton_clicked();
134134
void on_previousSymbolButton_clicked();
135135

136+
void on_actionFuzzyAutoComplete_toggled();
136137
void on_actionLiveSearch_toggled();
137138

138139
void frameSymbolLineEditChanged();

Model/qTagger/qTagger.cpp

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -522,6 +522,63 @@ int QTagger::levenshteinDistance(const QString &source, const QString &target)
522522
return previousColumn.at(targetCount);
523523
}
524524

525+
bool QTagger::fuzzyMatch(const QString& targetInput, const QString& patternInput, const Qt::CaseSensitivity& caseSensitivity)
526+
{
527+
int i = 0;
528+
int patternPos = 0;
529+
int matchedChar = 0;
530+
QString target, pattern;
531+
532+
if (caseSensitivity == Qt::CaseInsensitive) {
533+
target = targetInput.toLower();
534+
pattern = patternInput.toLower();
535+
} else {
536+
target = targetInput;
537+
pattern = patternInput;
538+
}
539+
540+
for (i = 0; i < target.length(); i++) {
541+
if (pattern.at(patternPos) == target.at(i)) {
542+
patternPos++;
543+
matchedChar++;
544+
} else {
545+
continue;
546+
}
547+
if (matchedChar == pattern.length()) { // all char in pattern match
548+
break;
549+
}
550+
if (patternPos >= pattern.length()) { // no match for all chars in pattern
551+
break;
552+
}
553+
if (i + pattern.length() - patternPos > target.length()) { // not match yet pattern reach end of string
554+
break;
555+
}
556+
}
557+
558+
if (matchedChar == pattern.length()) {
559+
return true;
560+
} else {
561+
return false;
562+
}
563+
}
564+
565+
int QTagger::getFuzzyMatchedTags(const QString& tagToQuery, QMap<int, QString>& matchedTokenList, const Qt::CaseSensitivity& caseSensitivity)
566+
{
567+
QStringList result;
568+
foreach (const CTagItem &tagItem, tagList_) {
569+
if (fuzzyMatch(tagItem.tag_, tagToQuery, caseSensitivity)) {
570+
int distance = levenshteinDistance(tagToQuery, tagItem.tag_);
571+
matchedTokenList[distance] = tagItem.tag_;
572+
}
573+
574+
if (matchedTokenList.size() > 500) {
575+
break;
576+
}
577+
}
578+
579+
return 0;
580+
}
581+
525582
int QTagger::getMatchedTags(const QString& tagToQuery, QMap<int, QString>& matchedTokenList, const Qt::CaseSensitivity& caseSensitivity)
526583
{
527584
QStringList result;

Model/qTagger/qTagger.h

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@
1919

2020
#include "CTagItem.h"
2121

22-
typedef QMap<QString, QString> T_TokenMapType;
22+
typedef QHash<QString, QString> T_TokenMapType;
2323

2424
class QTagger
2525
{
@@ -38,6 +38,10 @@ class QTagger
3838
int loadTagList(const QString& tagDbFileName);
3939

4040
int levenshteinDistance(const QString &source, const QString &target);
41+
42+
bool fuzzyMatch(const QString& targetInput, const QString& patternInput, const Qt::CaseSensitivity& caseSensitivity);
43+
int getFuzzyMatchedTags(const QString& tagToQuery, QMap<int, QString>& matchedTokenList, const Qt::CaseSensitivity& caseSensitivity);
44+
4145
int getMatchedTags(const QString& tagToQuery, QMap<int, QString>& matchedTokenList, const Qt::CaseSensitivity& caseSensitivity);
4246

4347
int queryTagLoadedSymbol(const T_FileItemList& inputFileItemList, const QString& tagToQuery,

README.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
![Blink logo](https://raw.githubusercontent.com/ychclone/blink/master/Resources/Images/graphics3.png)
22

33
# Blink code search
4-
GUI of live indexed grep for source code, files locator, search and replace.
5-
Switch different projects and start searching.
4+
GUI of live indexed grep for source code. Fuzzy suggestion in autocomplete.
5+
Files locator, search and replace. Switch different projects and start searching.
66
Drag and drop of filenames to your favourite editor.
77

88
[![Build status](https://ci.appveyor.com/api/projects/status/afn8q3ai3e7wphrf?svg=true)](https://ci.appveyor.com/project/ychclone/blink)
@@ -12,8 +12,8 @@ Drag and drop of filenames to your favourite editor.
1212

1313
# Features
1414
* Search without delay using prebuilt index, comparing to ack or ripgrep
15+
* Fuzzy suggestion in autocomplete
1516
* Live grep
16-
* Queries support autocomplete
1717
* Drag and drop for filename to your favourite editor
1818
* Switch between multiple projects
1919
* Very small index size compared to trigram

Resources/Forms/aboutDialog.ui

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@
6767
<item>
6868
<widget class="QLabel" name="label_5">
6969
<property name="text">
70-
<string>Blink v1.7.2</string>
70+
<string>Blink v1.7.3</string>
7171
</property>
7272
</widget>
7373
</item>

Resources/Forms/mainWindow.ui

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -690,6 +690,7 @@ background-color:qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, stop: 0 #e6f0fc, st
690690
<addaction name="actionSymbolCaseSensitive"/>
691691
<addaction name="actionSymbolRegularExpression"/>
692692
<addaction name="actionLiveSearch"/>
693+
<addaction name="actionFuzzyAutoComplete"/>
693694
</widget>
694695
<widget class="QMenu" name="menuProject">
695696
<property name="title">
@@ -1098,7 +1099,7 @@ background-color:qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, stop: 0 #e6f0fc, st
10981099
<normaloff>:/Icons/22x22/zoom-3.png</normaloff>:/Icons/22x22/zoom-3.png</iconset>
10991100
</property>
11001101
<property name="text">
1101-
<string>&amp;Replace in files</string>
1102+
<string>&amp;Replace in Files</string>
11021103
</property>
11031104
</action>
11041105
<action name="actionSymbolRegularExpression">
@@ -1138,6 +1139,14 @@ background-color:qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, stop: 0 #e6f0fc, st
11381139
<string>Live search</string>
11391140
</property>
11401141
</action>
1142+
<action name="actionFuzzyAutoComplete">
1143+
<property name="checkable">
1144+
<bool>true</bool>
1145+
</property>
1146+
<property name="text">
1147+
<string>Fuzzy Auto Complete</string>
1148+
</property>
1149+
</action>
11411150
</widget>
11421151
<customwidgets>
11431152
<customwidget>

Screencast/Usage.gif

1.49 MB
Loading

0 commit comments

Comments
 (0)