Skip to content

fix(pi-fff): make FffEditor safe under composability subclassing#436

Merged
dmtrKovalenko merged 1 commit intodmtrKovalenko:mainfrom
kylesnowschwartz:fix/pi-fff-mention-autocomplete-subclass-safety
May 2, 2026
Merged

fix(pi-fff): make FffEditor safe under composability subclassing#436
dmtrKovalenko merged 1 commit intodmtrKovalenko:mainfrom
kylesnowschwartz:fix/pi-fff-mention-autocomplete-subclass-safety

Conversation

@kylesnowschwartz
Copy link
Copy Markdown
Contributor

@kylesnowschwartz kylesnowschwartz commented May 2, 2026

Disclaimer: This PR was AI-generated (Claude / pi coding agent), reviewed by @kylesnowschwartz before submission.

Problem

When another extension installs a custom editor on top of pi-fff using the composability pattern from pi-mono#3935, typing @ to trigger file-mention autocomplete throws:

TypeError: getItems is not a function
    at Object.getSuggestions (.../@ff-labs/pi-fff/src/index.ts:157:27)

Confirmed against pi-vim and @jordyvd/pi-image-attachments.

Cause

pi-fff's factory took 4 args:

ctx.ui.setEditorComponent(
  (tui, theme, kb) => new FffEditor(tui, theme, kb, getMentionItems),
);

Wrapping extensions probe the previous factory, extract probe.constructor, and construct new Composed(tui, theme, kb) with only 3 args. FffEditor.getMentionItems becomes undefined. When setAutocompleteProvider runs, createFffMentionProvider(undefined) closes over getItems = undefined — the user's first @ press then throws.

Fix

Move the FffEditor class definition inside fffExtension() and capture getMentionItems via closure instead of through a constructor parameter. The factory now matches the standard (tui, theme, keybindings) shape, so any wrapper that subclasses FffEditor inherits a working mention provider regardless of how it constructs the instance.

Verification

Reproduced the failure end-to-end with pi-image-attachments's probe-and-subclass pattern against the unpatched FffEditor, and confirmed the patched class returns suggestions correctly under the same scenario:

probe.constructor = FffEditor
wrapped instance OK, calling setAutocompleteProvider...
provider exists: true
getSuggestions result: { items: [ ... 20 items ... ], prefix: '@he' }
PASS: no TypeError thrown

biome check reports the same 2 errors / 1 warning as main (both pre-existing, unrelated).

Compat

Public surface unchanged: factory signature, class name, mode behavior, all tools and commands identical. Pure internal refactor.

When pi-vim or pi-image-attachments wrap a previously-installed editor by
extracting `probe.constructor` and constructing `new SubClass(tui, theme,
keybindings)`, the 4th argument FffEditor relied on for `getMentionItems`
gets dropped. The mention provider closes over `undefined` and throws
`TypeError: getItems is not a function` the first time the user types `@`.

Move the FffEditor class definition inside fffExtension() so the override
captures `getMentionItems` via closure rather than via a constructor
parameter. The factory now matches the standard `(tui, theme, keybindings)`
shape, so any wrapper that subclasses FffEditor inherits a working mention
provider regardless of construction args.

Refs: badlogic/pi-mono#3935
Copy link
Copy Markdown
Owner

@dmtrKovalenko dmtrKovalenko left a comment

Choose a reason for hiding this comment

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

seems legit

@dmtrKovalenko dmtrKovalenko merged commit bcd3c76 into dmtrKovalenko:main May 2, 2026
40 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants