commit eefb3de54a5e03d944059460fe1caacdb8acb234 from: Omar Polo date: Sat Feb 26 22:44:24 2022 UTC tokenize minibuffer input for better matching instead of trying to match the given string as-is, split it into tokens (space-separated words) and try to match those. This allows to match out of order, for example "mir vid" will match gemini://vidage.rocks/blog/parliamo-di-mirror.gmi commit - 0e4c3d624c98e58a4d93f36569251c545e90f933 commit + eefb3de54a5e03d944059460fe1caacdb8acb234 blob - 9742b63b2d52dfc87ee1ba9956b9f9a368ad7584 blob + 6d49a0f0ba1c2f73d6b23fda3e00919f1aea027b --- ChangeLog +++ ChangeLog @@ -1,4 +1,8 @@ -2022-02-26 Omar Polo +2022-02-26 Omar Polo + + * minibuffer.c (recompute_completions): split the minibuffer input + into words and try to match every one of the independently from + the others. * cmd.c (cmd_load_url): remember visited URLs and provide completions during load-url. blob - 6f2e28cb6d6926f95e7b914d57a2dc0fab120741 blob + d303e21303f76bf05163e3830d131ac8c87c551c --- minibuffer.c +++ minibuffer.c @@ -26,6 +26,8 @@ #include "utf8.h" #include "utils.h" +#define nitems(x) (sizeof(x)/sizeof(x[0])) + static void *minibuffer_metadata(void); static void minibuffer_hist_save_entry(void); static void yornp_self_insert(void); @@ -55,7 +57,29 @@ struct ministate ministate; struct buffer minibufferwin; int in_minibuffer; + +static inline int +matches(char **words, size_t len, struct line *l) +{ + size_t i; + int lm, am; + + for (i = 0; i < len; ++i) { + lm = am = 0; + + if (strcasestr(l->line, words[i]) != NULL) + lm = 1; + if (l->alt != NULL && + strcasestr(l->alt, words[i]) != NULL) + am = 1; + + if (!lm && !am) + return 0; + } + return 1; +} + /* * Recompute the visible completions. If add is 1, don't consider the * ones already hidden. @@ -63,6 +87,9 @@ int in_minibuffer; void recompute_completions(int add) { + static char buf[GEMINI_URL_LEN]; + char *input, **ap, *words[10]; + size_t len = 0; struct line *l; struct vline *vl; struct buffer *b; @@ -70,13 +97,22 @@ recompute_completions(int add) if (in_minibuffer != MB_COMPREAD) return; + strlcpy(buf, ministate.buf, sizeof(buf)); + input = buf; + + /* tokenize the input */ + for (ap = words; ap < words + nitems(words) && + (*ap = strsep(&input, " ")) != NULL;) { + if (**ap != '\0') + ap++, len++; + } + b = &ministate.compl.buffer; TAILQ_FOREACH(l, &b->page.head, lines) { l->type = LINE_COMPL; if (add && l->flags & L_HIDDEN) continue; - if (strcasestr(l->line, ministate.buf) != NULL || - (l->alt != NULL && strcasestr(l->alt, ministate.buf) != NULL)) { + if (matches(words, len, l)) { if (l->flags & L_HIDDEN) b->line_max++; l->flags &= ~L_HIDDEN;