Skip to content

Fuzzy filter with a leading or trailing space hides every item: " hel" matches nothing, "hel " matches only items containing a space #115

Description

@matt-edmondson

What's wrong

The Fuzzy arm of IsMatch (TextFilter/TextFilter.cs:242) passes the filter to the fuzzy matcher exactly as typed:

TextFilterType.Fuzzy => Fuzzy.Contains(text.AsSpan(), filter.AsSpan(), out score),

A leading or trailing space therefore becomes a character the text must contain.

The other filter types don't behave this way. Glob and Regex split the filter into tokens, so padding has no effect. IsMatch itself already treats a filter that is only whitespace as "match everything". Fuzzy is the one type where a stray space changes the result.

Failure scenario

In a filter box, the user types a word, then a space before the next word. Every item without a space disappears. Leading spaces from a paste do the same.

With items {"hello world", "helium", "help", "yellow"}:

Filter Type Result Expected
"hel" Fuzzy [help, helium, hello world] same
"hel " Fuzzy [hello world] [help, helium, hello world]
" hel" Fuzzy [] [help, helium, hello world]
" hel*" Glob [hello world, helium, help] same

IsMatch("abcdef", "abc", Fuzzy) is true, but "abc " and " abc" both return false. Rank is unaffected, because it ignores the match result.

These results come from a scratch program built from the current TextFilter.cs against the pinned ktsu.FuzzySearch:

Fuzzy filter='hel' -> [help, helium, hello world]
Fuzzy filter='hel ' -> [hello world]
Fuzzy filter=' hel' -> []

Suggested fix

  • Trim the filter before the fuzzy match: Fuzzy.Contains(text.AsSpan(), filter.AsSpan().Trim(), out score).
  • Optionally, go further and apply TextFilterMatchOptions to fuzzy matching: split on whitespace and match each token, the way the glob path does. That would make "bar foo" fuzzy-match "foo bar". Today the match-options argument is silently ignored for Fuzzy.

Acceptance criteria

  • IsMatch(x, "hel ", Fuzzy) and IsMatch(x, " hel", Fuzzy) return the same result as IsMatch(x, "hel", Fuzzy) for every x.
  • Regression tests cover leading and trailing padding in Filter and IsMatch for Fuzzy.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    readyFully specified; implement as written

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions