From 748ef8b2ae314e2e5b99704cae0770632b32ed26 Mon Sep 17 00:00:00 2001 From: nicm Date: Tue, 23 Jun 2026 08:35:28 +0000 Subject: [PATCH] Extend match to do multiple terms. --- format.c | 34 +++++++++++++++++++++++++++++++--- tmux.1 | 3 ++- 2 files changed, 33 insertions(+), 4 deletions(-) diff --git a/format.c b/format.c index 797f64659..9aa6fc813 100644 --- a/format.c +++ b/format.c @@ -4507,11 +4507,14 @@ format_build_modifiers(struct format_expand_state *es, const char **s, return (list); } -/* Fuzzy match strings. */ +/* Fuzzy match a single token (no spaces). */ static int -format_fuzzy_match(const char *pattern, const char *text, int icase) +format_fuzzy_match_token(const char *pattern, size_t patternlen, + const char *text, int icase) { - while (*pattern != '\0') { + const char *end = pattern + patternlen; + + while (pattern != end) { if (*text == '\0') return (0); if (icase) { @@ -4526,6 +4529,31 @@ format_fuzzy_match(const char *pattern, const char *text, int icase) return (1); } +/* + * Fuzzy match strings. The pattern is split on spaces into tokens and every + * token must match as a sequence. + */ +static int +format_fuzzy_match(const char *pattern, const char *text, int icase) +{ + const char *start; + size_t len; + + while (*pattern != '\0') { + while (*pattern == ' ') + pattern++; + if (*pattern == '\0') + break; + start = pattern; + while (*pattern != '\0' && *pattern != ' ') + pattern++; + len = pattern - start; + if (!format_fuzzy_match_token(start, len, text, icase)) + return (0); + } + return (1); +} + /* Match against an fnmatch(3) pattern or regular expression. */ static char * format_match(struct format_modifier *fm, const char *pattern, const char *text) diff --git a/tmux.1 b/tmux.1 index 7f1403e73..dcb27b2fb 100644 --- a/tmux.1 +++ b/tmux.1 @@ -6385,7 +6385,8 @@ means the pattern is a regular expression instead of the default pattern, .Ql z means the pattern is a fuzzy match, that is, it matches if its characters -appear in the string in order but not necessarily consecutively, +appear in the string in order but not necessarily consecutively; +the pattern is split on spaces into separate terms which must all match, and .Ql i means to ignore case.