Skip to content

Commit dfd362e

Browse files
committed
liteeditor add fuzzy completion
1 parent 30f262d commit dfd362e

File tree

9 files changed

+104
-3
lines changed

9 files changed

+104
-3
lines changed

liteidex/src/api/liteeditorapi/liteeditorapi.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,7 @@ class ICompleter : public QObject
106106
virtual void setExternalMode(bool b) = 0;
107107
virtual bool externalMode() const = 0;
108108
virtual void setCaseSensitivity(Qt::CaseSensitivity caseSensitivity) = 0;
109+
virtual void setFuzzy(bool fuzzy) = 0;
109110
virtual void setCompletionPrefix(const QString &prefix) = 0;
110111
virtual QString completionPrefix() const = 0;
111112
virtual void setCompletionContext(CompletionContext ctx) = 0;

liteidex/src/plugins/liteeditor/codecompleter.cpp

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -297,6 +297,7 @@ CodeCompleterProxyModel::CodeCompleterProxyModel(QObject *parent)
297297
: QAbstractListModel(parent),m_model(0)
298298
{
299299
m_seperator = "::";
300+
m_fuzzy = false;
300301
}
301302

302303
CodeCompleterProxyModel::~CodeCompleterProxyModel()
@@ -523,6 +524,39 @@ int CodeCompleterProxyModel::filter(const QString &filter, int cs, LiteApi::Comp
523524
return m_items.size();
524525
}
525526

527+
//fuzzy completer
528+
if (m_fuzzy) {
529+
if (!prefix.isEmpty() && !( prefix[0].isLetter() || prefix[0] == '_') ) {
530+
return 0;
531+
}
532+
QString keyRegExp;
533+
if (!parentIndex.isValid()) {
534+
keyRegExp = "^";
535+
}
536+
foreach (const QChar &c, prefix) {
537+
keyRegExp += c;
538+
keyRegExp += "[0-9a-z_]*";
539+
}
540+
541+
QRegExp regExp(keyRegExp);
542+
regExp.setCaseSensitivity(Qt::CaseInsensitive);
543+
544+
int count = m_model->rowCount(parentIndex);
545+
QList<QStandardItem*> otherItems;
546+
for (int i = 0; i < count; i++) {
547+
QModelIndex index = m_model->index(i,0,parentIndex);
548+
QStandardItem *item = m_model->itemFromIndex(index);
549+
int n = regExp.indexIn(item->text());
550+
if (n == 0) {
551+
m_items.append(item->clone());
552+
} else if (n > 0) {
553+
otherItems.append(item->clone());
554+
}
555+
}
556+
m_items.append(otherItems);
557+
return m_items.size();
558+
}
559+
526560
QString keyRegExp;
527561
keyRegExp += QLatin1Char('^');
528562
bool first = true;
@@ -553,6 +587,7 @@ int CodeCompleterProxyModel::filter(const QString &filter, int cs, LiteApi::Comp
553587

554588
first = false;
555589
}
590+
556591
QRegExp regExp(keyRegExp);
557592

558593
int count = m_model->rowCount(parentIndex);
@@ -578,6 +613,16 @@ QString CodeCompleterProxyModel::separator() const
578613
return m_seperator;
579614
}
580615

616+
void CodeCompleterProxyModel::setFuzzy(bool b)
617+
{
618+
m_fuzzy = b;
619+
}
620+
621+
bool CodeCompleterProxyModel::isFuzzy() const
622+
{
623+
return m_fuzzy;
624+
}
625+
581626
CodeCompleterEx::CodeCompleterEx(QObject *parent)
582627
: QObject(parent), m_widget(0)
583628
{
@@ -803,6 +848,16 @@ bool CodeCompleterEx::wrapAround() const
803848
return m_wrap;
804849
}
805850

851+
void CodeCompleterEx::setFuzzy(bool b)
852+
{
853+
m_proxy->setFuzzy(b);
854+
}
855+
856+
bool CodeCompleterEx::isFuzzy() const
857+
{
858+
return m_proxy->isFuzzy();
859+
}
860+
806861
void CodeCompleterEx::completerActivated(QModelIndex index)
807862
{
808863
if (m_popup->isVisible()) {

liteidex/src/plugins/liteeditor/codecompleter.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,13 +97,16 @@ class CodeCompleterProxyModel : public QAbstractListModel
9797
int filter(const QString &filter, int cs = LiteApi::CaseInsensitive, LiteApi::CompletionContext ctx = LiteApi::CompleterCodeContext);
9898
void setSeparator(const QString &separator);
9999
QString separator() const;
100+
void setFuzzy(bool b);
101+
bool isFuzzy() const;
100102
protected:
101103
bool splitFilter(const QString &filter, QModelIndex &parent, QString &prefix, const QString &sep = ".");
102104
void clearItems();
103105
QList<QStandardItem*> m_items;
104106
QStringList m_importList;
105107
QStandardItemModel *m_model;
106108
QString m_seperator;
109+
bool m_fuzzy;
107110
};
108111

109112
class CodeCompleterEx : public QObject
@@ -133,6 +136,8 @@ class CodeCompleterEx : public QObject
133136
QAbstractItemModel *completionModel() const;
134137
void setWrapAround(bool wrap);
135138
bool wrapAround() const;
139+
void setFuzzy(bool b);
140+
bool isFuzzy() const;
136141
signals:
137142
void activated(QModelIndex);
138143
public slots:

liteidex/src/plugins/liteeditor/litecompleter.cpp

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -203,6 +203,26 @@ void LiteCompleter::showPopup()
203203
}
204204
//m_completer->model()->sort(0);
205205
m_completer->popup()->setCurrentIndex(m_completer->completionModel()->index(0, 0));
206+
QString prefix = m_completer->completionPrefix();
207+
if (!prefix.isEmpty()) {
208+
bool found = false;
209+
for (int i = 0; i < m_completer->completionModel()->rowCount(); i++) {
210+
QModelIndex index = m_completer->completionModel()->index(i,0);
211+
QString text = index.data().toString();
212+
if (text.startsWith(prefix,Qt::CaseInsensitive)) {
213+
if (text.compare(prefix,Qt::CaseInsensitive) == 0) {
214+
m_completer->popup()->setCurrentIndex(index);
215+
break;
216+
}
217+
if (!found) {
218+
m_completer->popup()->setCurrentIndex(index);
219+
}
220+
found = true;
221+
} else if (found) {
222+
break;
223+
}
224+
}
225+
}
206226
QTextCursor cursor = m_editor->textCursor();
207227
int offset = m_completer->completionPrefix().length();
208228
int pos = m_completer->completionPrefix().indexOf(m_completer->separator());
@@ -234,6 +254,11 @@ void LiteCompleter::setCaseSensitivity(Qt::CaseSensitivity caseSensitivity)
234254
m_completer->setCaseSensitivity(caseSensitivity);
235255
}
236256

257+
void LiteCompleter::setFuzzy(bool fuzzy)
258+
{
259+
m_completer->setFuzzy(fuzzy);
260+
}
261+
237262
void LiteCompleter::setCompletionPrefix(const QString &prefix)
238263
{
239264
m_completer->setCompletionPrefix(prefix);

liteidex/src/plugins/liteeditor/litecompleter.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,7 @@ class LiteCompleter : public LiteApi::ICompleter
5858
virtual void hidePopup();
5959
virtual bool isShowPopup();
6060
virtual void setCaseSensitivity(Qt::CaseSensitivity caseSensitivity);
61+
virtual void setFuzzy(bool fuzzy);
6162
virtual void setCompletionPrefix(const QString &prefix);
6263
virtual QString completionPrefix() const;
6364
virtual void setCompletionContext(LiteApi::CompletionContext ctx);

liteidex/src/plugins/liteeditor/liteeditor.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -964,6 +964,7 @@ void LiteEditor::applyOption(QString id)
964964
bool autoBraces4 = m_liteApp->settings()->value(EDITOR_AUTOBRACE4,true).toBool();
965965
bool autoBraces5 = m_liteApp->settings()->value(EDITOR_AUTOBRACE5,true).toBool();
966966
bool caseSensitive = m_liteApp->settings()->value(EDITOR_COMPLETER_CASESENSITIVE,false).toBool();
967+
bool fuzzyCompleter = m_liteApp->settings()->value(EDITOR_COMPLETER_FUZZY,false).toBool();
967968
bool lineNumberVisible = m_liteApp->settings()->value(EDITOR_LINENUMBERVISIBLE,true).toBool();
968969
bool codeFoldVisible = m_liteApp->settings()->value(EDITOR_CODEFOLDVISIBLE,true).toBool();
969970
bool rightLineVisible = m_liteApp->settings()->value(EDITOR_RIGHTLINEVISIBLE,true).toBool();
@@ -997,6 +998,7 @@ void LiteEditor::applyOption(QString id)
997998

998999
if (m_completer) {
9991000
m_completer->setCaseSensitivity(caseSensitive ? Qt::CaseSensitive : Qt::CaseInsensitive);
1001+
m_completer->setFuzzy(fuzzyCompleter);
10001002
}
10011003

10021004
updateFont();

liteidex/src/plugins/liteeditor/liteeditor_global.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@
5050
#define EDITOR_AUTOBRACE5 "editor/autobraces5"
5151
#define EDITOR_AUTOBRACE6 "editor/autobraces6"
5252
#define EDITOR_COMPLETER_CASESENSITIVE "editor/completercasesensitive"
53+
#define EDITOR_COMPLETER_FUZZY "editor/completerfuzzy"
5354
#define EDITOR_LINENUMBERVISIBLE "editor/linenumbervisible"
5455
#define EDITOR_VISUALIZEWHITESPACE "editor/visualizeWhitespace"
5556
#define EDITOR_PREFIXLENGTH "editor/prefixlength"

liteidex/src/plugins/liteeditor/liteeditoroption.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,7 @@ LiteEditorOption::LiteEditorOption(LiteApi::IApplication *app,QObject *parent) :
9898
bool autoBraces4 = m_liteApp->settings()->value(EDITOR_AUTOBRACE4,true).toBool();
9999
bool autoBraces5 = m_liteApp->settings()->value(EDITOR_AUTOBRACE5,true).toBool();
100100
bool caseSensitive = m_liteApp->settings()->value(EDITOR_COMPLETER_CASESENSITIVE,false).toBool();
101+
bool fuzzyCompleter = m_liteApp->settings()->value(EDITOR_COMPLETER_FUZZY,false).toBool();
101102
bool cleanWhitespaceOnSave = m_liteApp->settings()->value(EDITOR_CLEANWHITESPACEONSAVE,false).toBool();
102103
bool lineNumberVisible = m_liteApp->settings()->value(EDITOR_LINENUMBERVISIBLE,true).toBool();
103104
bool codeFoldVisible = m_liteApp->settings()->value(EDITOR_CODEFOLDVISIBLE,true).toBool();
@@ -124,6 +125,7 @@ LiteEditorOption::LiteEditorOption(LiteApi::IApplication *app,QObject *parent) :
124125
ui->visualizeWhitespaceCheckBox->setChecked(visualizeWhitespace);
125126
ui->codeFoldVisibleCheckBox->setChecked(codeFoldVisible);
126127
ui->completerCaseSensitiveCheckBox->setChecked(caseSensitive);
128+
ui->completerFuzzyCheckBox->setChecked(fuzzyCompleter);
127129
ui->preMinLineEdit->setText(QString("%1").arg(min));
128130
ui->cleanWhitespaceOnSaveCheckBox->setChecked(cleanWhitespaceOnSave);
129131
ui->rightLineVisibleCheckBox->setChecked(rightLineVisible);
@@ -228,6 +230,7 @@ void LiteEditorOption::apply()
228230
bool lineNumberVisible = ui->lineNumberVisibleCheckBox->isChecked();
229231
bool codeFoldVisible = ui->codeFoldVisibleCheckBox->isChecked();
230232
bool caseSensitive = ui->completerCaseSensitiveCheckBox->isChecked();
233+
bool fuzzyCompleter = ui->completerFuzzyCheckBox->isChecked();
231234
bool cleanWhitespaceOnSave = ui->cleanWhitespaceOnSaveCheckBox->isChecked();
232235
bool antialias = ui->antialiasCheckBox->isChecked();
233236
bool rightLineVisible = ui->rightLineVisibleCheckBox->isChecked();
@@ -260,6 +263,7 @@ void LiteEditorOption::apply()
260263
m_liteApp->settings()->setValue(EDITOR_DEFAULTWORDWRAP,defaultWordWrap);
261264
m_liteApp->settings()->setValue(EDITOR_INDENTLINEVISIBLE,indentLineVisible);
262265
m_liteApp->settings()->setValue(EDITOR_COMPLETER_CASESENSITIVE,caseSensitive);
266+
m_liteApp->settings()->setValue(EDITOR_COMPLETER_FUZZY,fuzzyCompleter);
263267
m_liteApp->settings()->setValue(EDITOR_PREFIXLENGTH,min);
264268
m_liteApp->settings()->setValue(EDITOR_CLEANWHITESPACEONSAVE,cleanWhitespaceOnSave);
265269
m_liteApp->settings()->setValue(EDITOR_RIGHTLINEVISIBLE,rightLineVisible);

liteidex/src/plugins/liteeditor/liteeditoroption.ui

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,8 @@
66
<rect>
77
<x>0</x>
88
<y>0</y>
9-
<width>479</width>
10-
<height>330</height>
9+
<width>612</width>
10+
<height>377</height>
1111
</rect>
1212
</property>
1313
<property name="windowTitle">
@@ -17,7 +17,7 @@
1717
<item>
1818
<widget class="QTabWidget" name="tabWidget">
1919
<property name="currentIndex">
20-
<number>0</number>
20+
<number>1</number>
2121
</property>
2222
<widget class="QWidget" name="tab">
2323
<attribute name="title">
@@ -265,6 +265,13 @@
265265
</property>
266266
</widget>
267267
</item>
268+
<item>
269+
<widget class="QCheckBox" name="completerFuzzyCheckBox">
270+
<property name="text">
271+
<string>Fuzzy code completion</string>
272+
</property>
273+
</widget>
274+
</item>
268275
<item>
269276
<widget class="QCheckBox" name="completerCaseSensitiveCheckBox">
270277
<property name="text">

0 commit comments

Comments
 (0)