From fa0d37bf4170582a6b8b5276487caf79aa1ced73 Mon Sep 17 00:00:00 2001 From: Alex Southwell <4596216+saphid@users.noreply.github.com> Date: Tue, 3 Nov 2026 11:22:20 +1100 Subject: [PATCH] fix(shared): find in thread matches a word typed with a curly apostrophe Co-Authored-By: Claude Opus 5.5 --- packages/shared/src/threadSearch.test.ts | 5 +++++ packages/shared/src/threadSearch.ts | 7 +++++-- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/packages/shared/src/threadSearch.test.ts b/packages/shared/src/threadSearch.test.ts index 83b87841c789a..fb52b2ec16a29 100644 --- a/packages/shared/src/threadSearch.test.ts +++ b/packages/shared/src/threadSearch.test.ts @@ -12,3 +12,8 @@ it("matches both Greek sigma forms without changing source offsets", () => { expect(findThreadSearchOccurrences("ΟΣ ος οσ", "ς")).toEqual([1, 4, 7]); expect(findThreadSearchOccurrences("İ ΟΣ", "Σ")).toEqual([3]); }); + +it("matches straight and curly apostrophes without changing source offsets", () => { + expect(findThreadSearchOccurrences("don't don’t", "don’t")).toEqual([0, 6]); + expect(findThreadSearchOccurrences("İ don‘t", "don't")).toEqual([2]); +}); diff --git a/packages/shared/src/threadSearch.ts b/packages/shared/src/threadSearch.ts index 5cca036d7bed4..6ffa12fcc1523 100644 --- a/packages/shared/src/threadSearch.ts +++ b/packages/shared/src/threadSearch.ts @@ -1,10 +1,13 @@ +// A typed straight apostrophe finds a curly one: iOS keyboards type "’". +const foldCharacters = (text: string) => text.replace(/ς/g, "σ").replace(/[‘’]/g, "'"); + function foldThreadSearchCase(text: string): string { - const lowered = text.toLowerCase().replace(/ς/g, "σ"); + const lowered = foldCharacters(text.toLowerCase()); if (lowered.length === text.length) return lowered; let folded = ""; for (const character of text) { - const loweredCharacter = character.toLowerCase().replace(/ς/g, "σ"); + const loweredCharacter = foldCharacters(character.toLowerCase()); folded += loweredCharacter.length === character.length ? loweredCharacter : character; } return folded;