uttrflow / uttrflow/uttrflow-swift
Every panel keystroke re-indents every code clip in the list to decide whether to offer Re-indent
- Dominant language
- Swift
- Stars
- 4
- Forks
- 17
- Avg merge
- 3h 32m
- Merged PRs (30d)
- 277
Description
## What happens
`PanelPresenter.present(_:)` builds a row for every listed clip on every keystroke: each arrow key, each letter typed into search, each redraw after a copy arrives (`Sources/Uttrflow/AppDelegate.swift:838`, `:863`, `:1095`). For each row it builds the ⋯ menu's actions, and for every code clip that includes:
```swift
// Sources/UttrflowUX/PanelPresentation.swift:453
if clip.kind == .code, CodeReindent.reindented(clip.text) != nil {
```
So the whole re-indent runs over the full text of every code clip in the list, on the main actor, to decide whether one menu item is shown. Nobody has opened the menu. The answer for a clip never changes, because its text does not change between keystrokes.
## Measured
A throwaway Release (`-O`) harness that links `UttrflowUX` and calls `PanelPresenter.present` directly. Apple silicon, averaged over 3 to 5 runs:
| List | `present` per keystroke |
|---|---|
| 1,000 short text clips | 8 ms |
| 100 code clips of 300 lines (about 16 KB each) | 151 ms, of which `CodeReindent` is 135 ms |
| 1,000 mixed clips, 50 of them 300-line code | 88 ms |
| the same plus one 1.8 MB code clip (under the 2 MB bound) | 266 ms |
| ↓ on that list (`applying(.down)` then `present`) | 283 ms |
`CodeReindent.reindented` on the 1.8 MB clip alone takes 160 ms.
## Why it matters
The panel is keyboard-first: ↑↓ and typing are the whole gesture. A developer's history is full of code clips, and each keystroke then costs a visible frame drop or more. On an 8 GB M1 Air the cost is higher, and it stays for as long as that one large clip is in history (7 days by default).
## How to reproduce
Build `PanelSnapshot(clips:now:)` with 100 `.code` clips of a few hundred indented lines each, then time `PanelPresenter.present(snapshot.applying(.down).state)`. Then remove the `CodeReindent` line and time it again.
## Acceptance criteria
- A keystroke does no work proportional to the text of clips the user has not opened a menu for. For example: decide "can be re-indented" once when the clip arrives or changes and store it, or build actions only for the selected row and the row whose menu is open.
- Re-indent is still offered exactly where it is today (the existing `PanelPresenter` action tests pass unchanged).
- A test in `Tests/UttrflowUXTests` shows that presenting a snapshot does not re-indent clips, by counting through a seam rather than by timing.
Contributor guide
Research direction
Start at PanelPresenter.present(_:) in Sources/Uttrflow/AppDelegate.swift and the action-building code in Sources/UttrflowUX/PanelPresentation.swift, especially the CodeReindent.reindented call. Run the existing PanelPresenter action tests, then add a seam-based test under Tests/UttrflowUXTests that counts re-indent checks during presentation. Done means presentation no longer re-indents clips unnecessarily while the existing Re-indent offering remains unchanged.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- swift
- Domain
- desktop-dev, performance
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Active
- Clarity
- Clearly specified
- Newbie friendliness
- 72/100