uttrflow / uttrflow/uttrflow-swift

Clipboard search ignores character width, and alias matching disagrees with search about nukta: "जिंदगी" finds a clip aliased "ज़िंदगी" but doesn't rank it as the alias

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

Description

## What happens

Every list search goes through one rule (`Sources/UttrflowUX/SearchMatching.swift:6-11`):

```swift
range(of: needle, options: [.caseInsensitive, .diacriticInsensitive], range: nil, locale: locale)
```

Alias matching reduces both sides with `folding` instead (`Sources/UttrflowUX/PanelAlias.swift:27-31`, used by `PanelResults.isAlias` at `Sources/UttrflowUX/PanelResults.swift:135-140`). Checked with a throwaway script calling the same Foundation APIs with the same options:

| clip text or alias | query | search (`range`) | alias equal (`folding`) |
|---|---|---|---|
| `ABC123` (full-width) | `abc123` | no match | — |
| `カタカナ` (half-width katakana) | `カタカナ` | no match | — |
| alias `ज़िंदगी` | `जिंदगी` | match | **not equal** |
| alias `Café` | `cafe` | match | equal |

- **Width.** Full-width Latin letters and digits are common in text copied from Japanese, Chinese and Korean pages and forms. Half-width katakana is common in older Japanese systems and receipts. Neither can be found by typing the usual form. Adding `.widthInsensitive` makes the first row match.
- **Nukta.** `range(of:options:.diacriticInsensitive)` ignores the Devanagari nukta (़, U+093C), but `folding(options:.diacriticInsensitive)` keeps it. So a Hindi alias typed without the nukta shows the clip, but as a content match. It loses the exact-alias ranking that `isAlias` exists to give, and the comment at `PanelResults.swift:137` says the two must "spell one name". Latin accents agree, which is why this hasn't shown up.

## Why it matters

Hindi is often typed without a nukta (ज़ → ज), and CJK text is full of full-width characters. Search should find a clip whichever way it was typed, and alias ranking should agree with search.

## Acceptance criteria

- `SearchMatching` adds `.widthInsensitive`.
- `PanelAlias.handle` gives the same answer as the search rule for the rows above. The simplest way is to also fold width, and to compare with `compare(_:options:range:locale:) == .orderedSame` using the same options instead of `folding` plus `==`. Or fold with the same options through a shared helper.
- Tests: in `Tests/UttrflowUXTests/PanelResultsTests.swift`, next to the existing "case and accents" test (around line 130), cover full-width and half-width katakana matches. In `Tests/UttrflowUXTests/PanelAliasTests.swift`, cover `ज़िंदगी`/`जिंदगी` being the same alias, and keep `Café`/`cafe`.

Not in scope: Arabic hamza forms (`أحمد` vs `احمد`) don't match either. Folding them is a normalisation choice rather than a bug, so leave it for a separate discussion.

## Where to start

- `Sources/UttrflowUX/SearchMatching.swift:6-11`
- `Sources/UttrflowUX/PanelAlias.swift:27-31`, `Sources/UttrflowUX/PanelResults.swift:135-140`
- Tests to extend: `Tests/UttrflowUXTests/PanelResultsTests.swift`, `Tests/UttrflowUXTests/PanelAliasTests.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:** S, about 2 hours.

Contributor guide

Open the contributing guide

Research direction

Read CONTRIBUTING.md, then inspect Sources/UttrflowUX/SearchMatching.swift, PanelAlias.swift, and PanelResults.swift. Extend PanelResultsTests.swift and PanelAliasTests.swift with the specified width and nukta cases while preserving the Café test. Run make verify with DEVELOPER_DIR set; done means search and alias ranking agree for all listed cases.

Written by the indexing model from the issue text.

Assessment

Tech stack
swift
Domain
desktop, search, testing
Issue type
Bug
Difficulty
2/5
Estimated time
1-3 hours
Activity status
Active
Clarity
Clearly specified
Newbie friendliness
86/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.