Repository navigation
fix(ime): ⌫ deletes the selection — empty commitText instead of caret-only deleteSurroundingText - #80
Merged
Merged
Conversation
…-only deleteSurroundingText
Heide (2026-10-29): "if you select something, whether it's everything
or partial, and you use the delete button on the toolbar, it doesn't do
anything. It only works when you don't have anything selected."
backspace() always called deleteSurroundingText(n, 0), which deletes
around the CARET — with an active selection (including one made by our
own Select All button) editors ignore it or no-op: the reported
dead ⌫.
performImeBackspace (extracted, unit-testable per the repo's
pure-logic pattern):
- selection present → commitText("", 1) — the canonical IME way to
replace a selection with nothing; DEL key-event fallback for editors
that refuse the empty commit
- caret → unchanged codepoint-correct backspace (surrogate-aware)
Six unit tests with a fake InputConnection pin the contract: selection
deleted via empty commit; refusing editor gets the DEL fallback; empty
selection falls through; caret/surrogate/empty-field cases preserved.
Signed-off-by: will wade <willwade@gmail.com>
…ome telemetry - I1 (the bug-#5 lesson): hostile editors (OneNote/Word class) return TRUE from commitText("") while doing nothing — the DEL fallback previously fired only on a false return, i.e. the failure mode real editors rarely produce. The selection path now re-verifies via getSelectedText: if the selection survived a true commit, the DEL fallback fires anyway (a lying editor that DID delete loses one char — the lesser evil vs. a dead ⌫). Test: the lying-editor case. - M4: performImeBackspace returns a sealed ImeBackspaceOutcome (SelectionDeleted/CaretDeleted/Noop); the toolbar reports state=selection|char|none in the ui_action backspace event — the distinction that motivated this fix. Schema state enum extended. - M2: the fake's getTextBeforeCursor now windows to the last n UTF-16 units (real semantics); fake selection state is now mutable so getSelectedText reflects the commit. Signed-off-by: will wade <willwade@gmail.com>
…telemetry symmetry, mapping pinned - NEW-1 (merge-blocker): the indent-2 rewrite of analytics-events.json reverted; the state enum extension is now the ONLY line changed, preserving the shared schema's formatting (reviewer: churn taxes every cross-repo sync of this hot file) - NEW-2: the ⌫ emits ui_action even with no connection (state no_connection) — a dead delete from a missing InputConnection is exactly the symptom class the telemetry should see - NEW-3: the outcome→state mapping moved onto ImeBackspaceOutcome (telemetryState) — testable, no duplicate string at the call site - Schema state description corrected (toggle states OR the delete kind) - Tests: empty surviving selection = success (no fallback fired); telemetry mapping pinned. 92 tests green. Signed-off-by: will wade <willwade@gmail.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Heide's 2026-10-29 report: "if you select something, whether it's everything or partial, and you use the delete button on the toolbar, it doesn't do anything. It only works when you don't have anything selected."
Root cause:
backspace()always calleddeleteSurroundingText(n, 0)— which deletes around the caret. With an active selection (including one made by our own Select All button), editors ignore or no-op it: a dead ⌫. The whole Select-All-then-delete flow — a core editing action for an AAC user — was broken.Fix: the logic is extracted to
performImeBackspace(ic)(the repo's pure-logic pattern, unit-testable with a fakeInputConnection):commitText("", 1)— the canonical IME way to replace a selection with nothing; a DEL key-event fallback covers editors that refuse the empty commitTests (6): selection deleted via empty commit; refusing editor gets the DEL fallback; empty-string selection falls through to caret behaviour; one-unit backspace; surrogate pair = 2 units; empty field = no-op.
(Also in her email thread: v0.1.26 confirmed working — "It's finally fixed!" — and she asked about seasonal emojis + skin tones in the Emoji alphabet, which is DasherCore data coverage, separate issue.)
Testing
assembleDebug+testDebugUnitTestgreen (90 tests)