Skip to content

Commit b6c792e

Browse files
committed
Add 'keywords' filter mode
1 parent 218374f commit b6c792e

File tree

1 file changed

+70
-17
lines changed

1 file changed

+70
-17
lines changed

wlines.c

+70-17
Original file line numberDiff line numberDiff line change
@@ -32,12 +32,18 @@
3232
#define DRAWTEXT_PARAMS (DT_NOCLIP | DT_NOPREFIX | DT_END_ELLIPSIS)
3333
#define FONT_HMARGIN(sz) (int)(state->settings.fontSize / 6)
3434

35+
typedef enum {
36+
FM_COMPLETE,
37+
FM_KEYWORDS,
38+
} filter_mode_t;
39+
3540
typedef struct {
3641
wchar_t *wndClass;
3742
int padding;
3843
char *fontName;
3944
char *promptText;
4045
int fontSize;
46+
filter_mode_t filterMode;
4147
bool caseSensitiveSearch;
4248
bool outputIndex;
4349
COLORREF bg, fg, bgSelect, fgSelect, bgEdit, fgEdit;
@@ -135,27 +141,59 @@ wchar_t *getTextboxString(state_t *state)
135141
return buf.data;
136142
}
137143

138-
void updateSearchResults(state_t *state)
144+
void filterReduceByStr(state_t *state, const wchar_t *str)
139145
{
140-
const wchar_t *str = getTextboxString(state);
146+
const size_t c = state->searchResultCount;
141147
state->searchResultCount = 0;
142-
if (wcslen(str) > 0) {
143-
if (state->settings.caseSensitiveSearch) {
144-
for (size_t i = 0; i < state->entryCount; i++) {
145-
if (wcsstr(state->entries[i], str)) {
146-
state->searchResults[state->searchResultCount++] = i;
147-
}
148-
}
149-
} else {
150-
for (size_t i = 0; i < state->entryCount; i++) {
151-
if (StrStrIW(state->entries[i], str)) {
152-
state->searchResults[state->searchResultCount++] = i;
153-
}
148+
if (state->settings.caseSensitiveSearch) {
149+
for (size_t i = 0; i < c; i++) {
150+
if (StrStrW(state->entries[state->searchResults[i]], str)) {
151+
state->searchResults[state->searchResultCount++] = state->searchResults[i];
154152
}
155153
}
156154
} else {
157-
for (size_t i = 0; i < state->entryCount; i++) {
158-
state->searchResults[state->searchResultCount++] = i;
155+
for (size_t i = 0; i < c; i++) {
156+
if (StrStrIW(state->entries[state->searchResults[i]], str)) {
157+
state->searchResults[state->searchResultCount++] = state->searchResults[i];
158+
}
159+
}
160+
}
161+
}
162+
163+
void filterReduceByKeywords(state_t *state, wchar_t *str)
164+
{
165+
// Iterate words and reduce results
166+
wchar_t *space;
167+
while ((space = StrStrW(str, L" "))) {
168+
space[0] = 0;
169+
if (wcslen(str) > 0) {
170+
filterReduceByStr(state, str);
171+
}
172+
str = space + 1;
173+
}
174+
if (wcslen(str) > 0) {
175+
filterReduceByStr(state, str);
176+
}
177+
}
178+
179+
void updateSearchResults(state_t *state)
180+
{
181+
// Put all entries into results
182+
state->searchResultCount = state->entryCount;
183+
for (size_t i = 0; i < state->entryCount; i++) {
184+
state->searchResults[i] = i;
185+
}
186+
187+
// Filter by chosen method
188+
wchar_t *str = getTextboxString(state);
189+
if (wcslen(str) > 0) {
190+
switch (state->settings.filterMode) {
191+
case FM_COMPLETE:
192+
filterReduceByStr(state, str);
193+
break;
194+
case FM_KEYWORDS:
195+
filterReduceByKeywords(state, str);
196+
break;
159197
}
160198
}
161199

@@ -205,7 +243,7 @@ LRESULT CALLBACK editWndProc(HWND wnd, UINT msg, WPARAM wparam, LPARAM lparam)
205243
default:
206244
result = CallWindowProc(state->editWndProc, wnd, msg, wparam, lparam);
207245
}
208-
updateSearchResults(state);
246+
updateSearchResults(state); // TODO: debounce on large entry set?
209247
return result;
210248
case WM_KEYDOWN: // When a key is pressed
211249
switch (wparam) {
@@ -600,6 +638,7 @@ void usage()
600638
"OPTIONS:\n"
601639
"\t-l <count> Amount of lines to show in list\n"
602640
"\t-p <text> Prompt to show before input\n"
641+
"\t-fm <mode> Sets the desired filter mode (see list below)\n"
603642
"\t-si <index> Initial selected line index\n"
604643
"\t-px <pixels> Sets padding on window\n"
605644
"\t-wx <pixels> Sets width of the window and centers it on the screen\n"
@@ -612,6 +651,10 @@ void usage()
612651
"\t-f <font> Font name\n"
613652
"\t-fs <size> Font size\n"
614653
"\n"
654+
"FILTER MODES:\n"
655+
"\tcomplete Filter on the entire search string (default)\n"
656+
"\tkeywords Filter on all individual space-delimited words in the search string\n"
657+
"\n"
615658
"KEYBINDS:\n"
616659
"\tEnter Output selected line\n"
617660
"\t[HELD] Ctrl Don't quit after outputting\n"
@@ -638,6 +681,7 @@ int main(int argc, char **argv)
638681
.settings = {
639682
.wndClass = L"wlines_window",
640683
.padding = 4,
684+
.filterMode = FM_COMPLETE,
641685
.caseSensitiveSearch = false,
642686
.bg = parseColor("#000000"),
643687
.fg = parseColor("#ffffff"),
@@ -672,6 +716,15 @@ int main(int argc, char **argv)
672716
// TODO: encoding for windows arugments is strange
673717
// look into using `wmain` or `GetCommandLineW`
674718
state.settings.promptText = argv[++i];
719+
} else if (!strcmp(argv[i], "-fm")) {
720+
const char *modeStr = argv[++i];
721+
if (!strcmp(modeStr, "complete")) {
722+
state.settings.filterMode = FM_COMPLETE;
723+
} else if (!strcmp(modeStr, "keywords")) {
724+
state.settings.filterMode = FM_KEYWORDS;
725+
} else {
726+
usage();
727+
}
675728
} else if (!strcmp(argv[i], "-si")) {
676729
state.settings.selectedIndex = atoi(argv[++i]);
677730
if (state.settings.selectedIndex < 0) {

0 commit comments

Comments
 (0)