32
32
#define DRAWTEXT_PARAMS (DT_NOCLIP | DT_NOPREFIX | DT_END_ELLIPSIS)
33
33
#define FONT_HMARGIN (sz ) (int)(state->settings.fontSize / 6)
34
34
35
+ typedef enum {
36
+ FM_COMPLETE ,
37
+ FM_KEYWORDS ,
38
+ } filter_mode_t ;
39
+
35
40
typedef struct {
36
41
wchar_t * wndClass ;
37
42
int padding ;
38
43
char * fontName ;
39
44
char * promptText ;
40
45
int fontSize ;
46
+ filter_mode_t filterMode ;
41
47
bool caseSensitiveSearch ;
42
48
bool outputIndex ;
43
49
COLORREF bg , fg , bgSelect , fgSelect , bgEdit , fgEdit ;
@@ -135,27 +141,59 @@ wchar_t *getTextboxString(state_t *state)
135
141
return buf .data ;
136
142
}
137
143
138
- void updateSearchResults (state_t * state )
144
+ void filterReduceByStr (state_t * state , const wchar_t * str )
139
145
{
140
- const wchar_t * str = getTextboxString ( state ) ;
146
+ const size_t c = state -> searchResultCount ;
141
147
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 ];
154
152
}
155
153
}
156
154
} 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 ;
159
197
}
160
198
}
161
199
@@ -205,7 +243,7 @@ LRESULT CALLBACK editWndProc(HWND wnd, UINT msg, WPARAM wparam, LPARAM lparam)
205
243
default :
206
244
result = CallWindowProc (state -> editWndProc , wnd , msg , wparam , lparam );
207
245
}
208
- updateSearchResults (state );
246
+ updateSearchResults (state ); // TODO: debounce on large entry set?
209
247
return result ;
210
248
case WM_KEYDOWN : // When a key is pressed
211
249
switch (wparam ) {
@@ -600,6 +638,7 @@ void usage()
600
638
"OPTIONS:\n"
601
639
"\t-l <count> Amount of lines to show in list\n"
602
640
"\t-p <text> Prompt to show before input\n"
641
+ "\t-fm <mode> Sets the desired filter mode (see list below)\n"
603
642
"\t-si <index> Initial selected line index\n"
604
643
"\t-px <pixels> Sets padding on window\n"
605
644
"\t-wx <pixels> Sets width of the window and centers it on the screen\n"
@@ -612,6 +651,10 @@ void usage()
612
651
"\t-f <font> Font name\n"
613
652
"\t-fs <size> Font size\n"
614
653
"\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"
615
658
"KEYBINDS:\n"
616
659
"\tEnter Output selected line\n"
617
660
"\t[HELD] Ctrl Don't quit after outputting\n"
@@ -638,6 +681,7 @@ int main(int argc, char **argv)
638
681
.settings = {
639
682
.wndClass = L"wlines_window" ,
640
683
.padding = 4 ,
684
+ .filterMode = FM_COMPLETE ,
641
685
.caseSensitiveSearch = false,
642
686
.bg = parseColor ("#000000" ),
643
687
.fg = parseColor ("#ffffff" ),
@@ -672,6 +716,15 @@ int main(int argc, char **argv)
672
716
// TODO: encoding for windows arugments is strange
673
717
// look into using `wmain` or `GetCommandLineW`
674
718
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
+ }
675
728
} else if (!strcmp (argv [i ], "-si" )) {
676
729
state .settings .selectedIndex = atoi (argv [++ i ]);
677
730
if (state .settings .selectedIndex < 0 ) {
0 commit comments