diff options
| -rw-r--r-- | args.c | 13 | ||||
| -rw-r--r-- | config.h | 2 | ||||
| -rw-r--r-- | input_field.c | 46 | ||||
| -rw-r--r-- | main.c | 1 | ||||
| -rw-r--r-- | state.h | 3 |
5 files changed, 57 insertions, 8 deletions
@@ -13,12 +13,14 @@ void parse_args(client_state* state, int argc, char* argv[]) { {"verbose", no_argument, 0, 'v'}, {"password", no_argument, 0, 'P'}, {"prompt", no_argument, 0, 'p'}, + {"orderless", no_argument, 0, 'o'}, + {"insensitive", no_argument, 0, 'i'}, {0, 0, 0, 0} }; int opt; int long_index = 0; - while ((opt = getopt_long(argc, argv, "l:p:cevP", long_opts, &long_index)) != -1) { + while ((opt = getopt_long(argc, argv, "l:p:coievP", long_opts, &long_index)) != -1) { switch (opt) { case 'l': state->lines = atoi(optarg); @@ -29,7 +31,7 @@ void parse_args(client_state* state, int argc, char* argv[]) { case 'c': state->center = true; break; - case 'a': + case 'e': state->exact_match = true; break; case 'v': @@ -38,8 +40,15 @@ void parse_args(client_state* state, int argc, char* argv[]) { case 'P': state->password = true; break; + case 'o': + state->orderless = true; + break; + case 'i': + state->strstr = strcasestr; + break; default: fprintf(stderr, "Usage: NOT WHAT YOU TYPED\n"); + fprintf(stderr, "%c\n", opt); break; } } @@ -10,7 +10,7 @@ typedef struct { static const bool fancy_scroll = false; static const uint32_t min_width = 500; -static const uint32_t font_size = 15; +static const uint32_t font_size = 16; static const color_t text_color = {0.85, 0.85, 0.85, 1.0}; static const color_t highlight_color = {0.1, 0.3, 0.7, 1.0}; static const color_t background_color = {0.1, 0.1, 0.1, 1.0}; diff --git a/input_field.c b/input_field.c index ad94104..bd8b93e 100644 --- a/input_field.c +++ b/input_field.c @@ -9,6 +9,10 @@ int compare(const void *a, const void *b) { return strlen(((item_display_t*)a)->item->text) > strlen(((item_display_t*)b)->item->text); } +int orderless_compare(const void *a, const void *b) { + return ((item_display_t*)a)->perc < ((item_display_t*)b)->perc; +} + void filter_items(client_state* state) { if (!state->items) return; @@ -20,13 +24,45 @@ void filter_items(client_state* state) { // add all strings with substring array_clear(state->filtered_items); - array_for_all(item_t, i, state->items) { - if (strstr(i->text, input_buffer_string) != NULL) { - array_add(state->filtered_items, (item_display_t){ .item = i }); + if (state->orderless) { + char** parts = array_new(char*, 0); + char* part = NULL; + for (part = strtok(input_buffer_string, " "); part; part = strtok(NULL, " ")) { + array_add(parts, part); + } + array_for_all(item_t, i, state->items) { + float total = strlen(i->text); + float part = 0; + bool add = true; + array_for_all(char*, j, parts) { + if (state->strstr(i->text, *j)) { + part += strlen(*j); + } + else { + add = false; + } + } + if (add) { + item_display_t tmp = { + .item = i, + .perc = part / total + }; + array_add(state->filtered_items, tmp); + } + } + if (array_size(state->input_buffer)) { + qsort(state->filtered_items, array_size(state->filtered_items), sizeof(item_display_t), orderless_compare); } } - if (array_size(state->input_buffer)) { - qsort(state->filtered_items, array_size(state->filtered_items), sizeof(item_display_t), compare); + else { + array_for_all(item_t, i, state->items) { + if (state->strstr(i->text, input_buffer_string) != NULL) { + array_add(state->filtered_items, (item_display_t){ .item = i }); + } + } + if (array_size(state->input_buffer)) { + qsort(state->filtered_items, array_size(state->filtered_items), sizeof(item_display_t), compare); + } } // select item @@ -45,6 +45,7 @@ int main(int argc, char* argv[]) { state.filtered_items = array_new(item_display_t, 0); state.selected_filtered_item = -1; state.page_indices = array_new(size_t, 0); + state.strstr = strstr; // check locale setlocale(LC_ALL, ""); @@ -53,6 +53,7 @@ typedef struct { typedef struct { item_t* item; rect_t r; + float perc; } item_display_t; typedef struct { @@ -119,6 +120,8 @@ typedef struct { bool center; bool verbose; bool password; + bool orderless; + char* (*strstr)(const char*, const char*); // input item_t* items; |
