uttrflow / uttrflow/uttrflow-swift

Clip.summary splits the whole clip into lines to show its first one, on every row of every panel redraw

Open Beginner friendly
#575 0 comments 0 reactions 0 assignees View on GitHub
area:clipboard bug good first issue P2 performance
Dominant language
Swift
Stars
4
Forks
17
Avg merge
3h 32m
Merged PRs (30d)
277

Description

## What happens

`Clip.summary` (`Sources/UttrflowClipboard/Clip.swift:115-120`) is the one line a row shows:

```swift
text.split(whereSeparator: \.isNewline)
.first
.map(String.init)?
.trimmingCharacters(in: .whitespaces) ?? ""
```

`split` walks the whole clip and builds every line to keep only the first. `PanelPresenter.row(for:in:isSelected:)` reads it for every listed row on every keystroke (`Sources/UttrflowUX/PanelPresentation.swift:371`). The result is also not capped. A single-line clip, such as minified code or a log line, becomes the row's `Text`, its tooltip (`QuickPanelView.swift:424`) and its VoiceOver label (`QuickPanelRowAppearance.swift:43`) at full length, up to the 2 MB clip bound.

## Measured

Throwaway Release harness, Apple silicon:

- `summary` over 916 clips of 8 to 16 KB each: **116 ms**. `PanelPresenter.present` after ↓ on the same list: 116 ms, so almost all of each arrow key is this.
- `summary` on one 1.8 MB multi-line clip: 19 ms, every redraw.

## Why it matters

A full history (the copied pool holds up to 8 MB) makes every arrow key and every search letter lag. A VoiceOver user who lands on a long one-line clip hears all of it.

## Acceptance criteria

- `summary` reads only as far as the first line break, or a fixed number of characters if that comes first, whichever is sooner. It never visits the rest of the clip.
- The summary is capped at a length a 420-point row can use (a few hundred characters). Truncation stays the view's job.
- Tests in `Tests/UttrflowClipboardTests/ClipTests.swift`: the first line is unchanged for ordinary clips; a clip whose first line is longer than the cap comes back capped; leading whitespace and CRLF behave as today.

## Where to start

- `Sources/UttrflowClipboard/Clip.swift:114-120`
- Test to extend: `Tests/UttrflowClipboardTests/ClipTests.swift`
- Before pushing, run `make verify` (export `DEVELOPER_DIR=/Applications/Xcode.app/Contents/Developer` first). It is the same command CI runs, and it enforces the 95% coverage floor per module.
- Read [CONTRIBUTING.md](https://github.com/uttrflow/uttrflow-swift/blob/main/CONTRIBUTING.md) first, and say on this issue that you are taking it.

**Size:** XS to S, about 1 to 2 hours.

Contributor guide

Open the contributing guide

Research direction

Read CONTRIBUTING.md, then inspect Clip.summary in Sources/UttrflowClipboard/Clip.swift:114-120 and extend Tests/UttrflowClipboardTests/ClipTests.swift. Verify ordinary first lines, the cap, leading whitespace, and CRLF behavior while ensuring reading stops at the first line break or cap. Run make verify with the specified DEVELOPER_DIR; done means the tests pass and summaries are bounded for redraws and accessibility labels.

Written by the indexing model from the issue text.

Assessment

Tech stack
swift
Domain
accessibility, performance
Issue type
Bug
Difficulty
2/5
Estimated time
1-3 hours
Activity status
Active
Clarity
Clearly specified
Newbie friendliness
90/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.