Skip to content

fix(core): skip double-filtering when options is a function#489

Open
brick-pixel wants to merge 3 commits intobombshell-dev:mainfrom
brick-pixel:fix/autocomplete-double-filter
Open

fix(core): skip double-filtering when options is a function#489
brick-pixel wants to merge 3 commits intobombshell-dev:mainfrom
brick-pixel:fix/autocomplete-double-filter

Conversation

@brick-pixel
Copy link

@brick-pixel brick-pixel commented Mar 16, 2026

What

When options is provided as a function, the autocomplete prompt no longer applies the default filter on top of the function's already-filtered results.

Why

As reported in #488, when options is a function (e.g. using fuzzysort for custom ranking), clack's default substring filter runs on the returned list, silently dropping valid matches. This forces users to add filter: () => true as a workaround.

Root cause: In #onUserInputChanged, this.#filterFn is always applied to the result of this.options, regardless of whether options is a static array or a dynamic function.

Changes

File: packages/core/src/prompts/autocomplete.ts

  • Added #hasCustomFilter field to track whether a custom filter was provided
  • When options is a function and no custom filter was provided, the returned options are used as-is
  • When both options (function) and filter are provided, the filter is still applied as before

Behavior Matrix

options filter Behavior
Array Not provided Default filter applied ✅ (unchanged)
Array Custom function Custom filter applied ✅ (unchanged)
Function Not provided No filter applied ✅ (fixed)
Function Custom function Custom filter applied ✅ (unchanged)

Verification

  • All existing tests pass (630 tests, 0 failures)
  • Lint and format checks pass (biome)

Fixes #488

When `options` is provided as a function, the caller manages their own
filtering (e.g. using fuzzysort). The autocomplete prompt was applying
its default filter on top of the already-filtered results, silently
dropping valid matches.

Now, when `options` is a function and no custom `filter` was provided,
the returned options are used as-is without additional filtering.

If both `options` (function) and `filter` are provided, the filter is
still applied as before, giving full control to the caller.

Fixes bombshell-dev#488
@changeset-bot
Copy link

changeset-bot bot commented Mar 16, 2026

🦋 Changeset detected

Latest commit: c900cf7

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 2 packages
Name Type
@clack/core Minor
@clack/prompts Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@43081j
Copy link
Collaborator

43081j commented Mar 17, 2026

for some context (cc @dreyfus92 too), we (or at least i) were aware of this. it is not a bug, it was an active decision that if you want to do your own filtering, you need to pass a noop filter until we get around to deciding how to solve it in a better way.

so we're just now at the point of "deciding how to solve it in a better way".

just wanted to make that clear so we're aware this is not a bug we're fixing. it is a behavioural change and a feat.

not all custom options functions do their own filtering, which is why we didn't simply turn it off like in this PR.

i feel like it is a rare case, though, to have the need for an options function and not do your own filtering. so i think i am happy to change this. just make sure you update the PR title etc to feat

Copy link
Collaborator

@43081j 43081j left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ah lastly can you add tests for the new branches?

  • setting an options function doesn't apply the default filter
  • setting a filter and an options function works (i.e. both run)

@brick-pixel
Copy link
Author

Thanks for the context! Updated the PR:

  • Title changed to feat
  • Changeset bumped from patch to minor since this is a behavioral change

Makes sense that not all custom options functions do their own filtering. With this change, filter still works normally when explicitly provided alongside a function options — only the implicit default filter is skipped.

@brick-pixel
Copy link
Author

Added the tests — one for options function without filter (default filter skipped) and one with both options function and custom filter (filter still runs). All 98 core tests passing.

});

test('options function skips default filter when no custom filter provided', () => {
const optionsFn = function (this: any) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

you don't need any in this repo as we always have a type. this one is an AutocompletePrompt

input.emit('keypress', 'b', { name: 'b' });

// Should use the options function result as-is, no additional filtering
expect(instance.filteredOptions).toEqual([
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

wouldn't this pass if the default filter was being applied too?

you should probably make your options function do some unusual filtering. e.g. filter to a constant result

@github-actions github-actions bot added the automated PR author detected as automated label Mar 18, 2026
@github-actions
Copy link
Contributor

🤖 Automated account detected

@brick-pixel has been flagged as a likely automated account.

Classification: automation (score: 5)

Signal Points Detail
Recently created +20 Account is 5 days old
Frequent repository creation +25 12 repositories created in a short timeframe (within 24 hours)
High PR volume +20 16 PRs in 3 days
Many recent forks +30 17 repos forked recently

Analyzed 61 public events via voight-kampff-test

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

Labels

automated PR author detected as automated

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug] filter + options() double-filtering issue for autocomplete

2 participants