Skip to content

Fill Quick Access auto slots from used symbols too - #247

Merged
wr merged 1 commit into
wr:mainfrom
sethfitz:wells/quick-access-auto-fill-symbols
Nov 4, 2026
Merged

wr merged 1 commit into
wr:mainfrom
sethfitz:wells/quick-access-auto-fill-symbols

Conversation

@sethfitz

@sethfitz sethfitz commented Nov 4, 2026

Copy link
Copy Markdown
Contributor

Summary

Symbols you use now fill Quick Access auto slots the way emoji do. Before, a used emoji like 🧀 appeared in the bare-: pill, the browser's Quick Access section and the Settings slot grid, and a used symbol like → never did, however often it was inserted.

Engine.recordUsage counts a symbol in usageCounts under its synthetic SYM_… hexcode (SYM_arrow_right for →). QuickAccess.resolvedPerSlot dropped every SYM_ key from the auto-fill pool, and resolved the rest only through the emoji database, which has no symbols. It now keeps SYM_ keys and resolves them through SymbolsDatabase, as pinned symbol slots already did; a new QuickAccess.lookup serves pinned and auto slots. Existing users who insert symbols often will see those symbols take auto slots after updating.

While the Symbols trigger is off, used symbols stay out of the auto slots, as the browser already hides its symbols section then. A pinned symbol still shows: pinning it was an explicit choice. resolvedPerSlot takes the trigger state as symbolsEnabled.

A symbol typed in full (::arrow_right:) was never counted, so it could not reach an auto slot even with that fix. The exact-match symbol path now goes through recordUsage like the emoji one. Those inserts now also raise the symbol's rank in search, as a picked symbol already did, and reach the symbol telemetry count, where they were missing.

Resolving a symbol needs SymbolsDatabase.byHexcode, built by a CoreText sweep on first access (about 130 ms, measured in a unit test). The bare-: pill is built inside the event-tap callback, so left alone, the first : after launch would hold that keystroke, and the pill, for the length of the sweep. Instead, search, the browser and byHexcode now share one sweep (SymbolsDatabase.all; each used to run its own), and launch runs it on a utility queue when a pin includes a symbol, or, with Symbols on, stored usage does. Users who never insert a symbol don't pay for it. A : typed before the warm-up finishes waits for it, no worse than before.

  • Sources/Mojito/EmojiDB/QuickAccessStore.swift: auto-fill keeps SYM_ keys while Symbols is on; lookup.
  • Sources/Mojito/App/Engine.swift, Browser/EmojiBrowserViewModel.swift, Settings/QuickAccessSettings.swift: pass the Symbols trigger state to Quick Access.
  • Sources/Mojito/EmojiDB/SymbolsDatabase.swift, FuzzyMatcher.swift, Browser/EmojiBrowserViewModel.swift, Debug/DebugReport.swift: one shared all.
  • Sources/Mojito/App/AppDelegate.swift: the launch warm-up; CLAUDE.md says to use all.
  • Sources/Mojito/App/Engine.swift: exact-typed symbols record usage.
  • Tests/MojitoTests/FavoritesBrowseTests.swift: resolvedAutoFillsUsedSymbols (a symbol used more often than an emoji takes the first auto slot) and resolvedSkipsUsedSymbolsWhenSymbolsOff (with Symbols off, a used symbol takes no auto slot and a pinned one stays).

Test plan

  • scripts/run-tests.sh passes.
  • With the auto-fill change reverted, resolvedAutoFillsUsedSymbols fails: the slots contain only the emoji. Without the Symbols-off filter, resolvedSkipsUsedSymbolsWhenSymbolsOff fails: the used symbol takes an auto slot.
  • In the Debug build (Mojito Dev): after inserting →, a bare : shows → in the Quick Access pill.
  • In the Debug build, with Symbols turned off in Settings, → leaves the pill's auto slots, and a pinned symbol stays.

A used emoji filled a Quick Access auto slot; a used symbol (→) never
did. Auto-fill dropped every SYM_ key from usageCounts and resolved the
rest only through the emoji database. It now keeps them and resolves
them through SymbolsDatabase, as pinned symbol slots already did. While
the Symbols trigger is off, used symbols stay out of the auto slots; a
pinned symbol still shows.

Symbols typed in full (`::arrow_right:`) were never recorded as used, so
they could not reach a slot either. The exact-match symbol path now goes
through recordUsage like the emoji one, which also feeds the search
frequency boost and the symbol telemetry count.

Resolving a symbol runs the CoreText sweep on first access, and the
bare-`:` pill is built inside the event-tap callback. Search, the
browser and byHexcode now share one sweep (SymbolsDatabase.all), and
launch runs it on a utility queue when a pin, or with Symbols on a used
symbol, needs it, so the first `:` doesn't wait on it.
@wr
wr merged commit ff4f71d into wr:main Nov 4, 2026
3 checks passed
@sethfitz
sethfitz deleted the wells/quick-access-auto-fill-symbols branch November 4, 2026 18:59
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