From 4a57000c38d12ab97631bda77c646e631aafad35 Mon Sep 17 00:00:00 2001 From: Thomas Richter Date: Sun, 1 Feb 2026 22:17:39 +0100 Subject: [PATCH] fix: only parse complete hashtags (followed by word boundary) Prevents incomplete hashtags from being saved during typing when auto-save fires mid-word. Co-Authored-By: Claude Opus 4.5 --- src/lib/utils/parseHashtags.ts | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/lib/utils/parseHashtags.ts b/src/lib/utils/parseHashtags.ts index b5b3d3c..4cfea5c 100644 --- a/src/lib/utils/parseHashtags.ts +++ b/src/lib/utils/parseHashtags.ts @@ -1,9 +1,11 @@ /** * Extract hashtags from text content - * Matches #word patterns, supporting alphanumeric and underscores + * Matches #word patterns followed by word boundary (space, punctuation, or end of text) + * This prevents capturing incomplete hashtags during typing */ export function parseHashtags(text: string): string[] { - const hashtagRegex = /#([a-zA-Z][a-zA-Z0-9_]*)/g; + // Match hashtags followed by word boundary, whitespace, punctuation, or end of string + const hashtagRegex = /#([a-zA-Z][a-zA-Z0-9_]*)(?=[\s\p{P}]|$)/gu; const matches = text.matchAll(hashtagRegex); const tags = new Set(); @@ -17,6 +19,7 @@ export function parseHashtags(text: string): string[] { /** * Highlight hashtags in text for display * Returns HTML with hashtags wrapped in styled spans + * Only highlights complete hashtags (followed by space, punctuation, or end) */ export function highlightHashtags(text: string): string { const escaped = text @@ -25,7 +28,7 @@ export function highlightHashtags(text: string): string { .replace(/>/g, '>'); return escaped.replace( - /#([a-zA-Z][a-zA-Z0-9_]*)/g, + /#([a-zA-Z][a-zA-Z0-9_]*)(?=[\s\p{P}]|$)/gu, '#$1' ); }