From 5f18d727e1841c47c1841faff097f7a144c7494c Mon Sep 17 00:00:00 2001 From: Daneel Date: Wed, 4 Mar 2026 13:38:54 +0100 Subject: [PATCH] patches: fix em-dash and SPECPDL_INDEX ordering Replace all Unicode em-dashes (---) with ASCII triple-dash (---) across 0001-0007 (39 occurrences). GNU Emacs source files must be ASCII; em-dash in comments would cause encoding issues on some systems. Fix SPECPDL_INDEX() call order in postCompletionAnnouncementForBuffer: (0003): specpdl_ref must be taken BEFORE block_input() so the snapshot captures the pre-block_input specpdl depth. This matches the pattern established in patches 0001 and 0002. --- ...lity-base-classes-and-text-extractio.patch | 12 +++---- ...fer-accessibility-element-core-proto.patch | 12 +++---- ...tification-dispatch-and-mode-line-el.patch | 10 +++--- ...essibility-with-EmacsView-and-redisp.patch | 12 +++---- ...lay-completion-candidates-for-VoiceO.patch | 34 +++++++++---------- 5 files changed, 40 insertions(+), 40 deletions(-) diff --git a/patches/0001-ns-add-accessibility-base-classes-and-text-extractio.patch b/patches/0001-ns-add-accessibility-base-classes-and-text-extractio.patch index ca01180..7d99039 100644 --- a/patches/0001-ns-add-accessibility-base-classes-and-text-extractio.patch +++ b/patches/0001-ns-add-accessibility-base-classes-and-text-extractio.patch @@ -52,11 +52,11 @@ index ea6e7ba4f5..f245675513 100644 +/* Base class for virtual accessibility elements attached to EmacsView. */ +@interface EmacsAccessibilityElement : NSAccessibilityElement +@property (nonatomic, unsafe_unretained) EmacsView *emacsView; -+/* Lisp window object — safe across GC cycles. ++/* Lisp window object --- safe across GC cycles. + GC safety: these Lisp_Objects are NOT visible to GC via staticpro + or the specpdl stack. This is safe because: + (1) Emacs GC runs only on the main thread, at well-defined safe -+ points during Lisp evaluation — never during redisplay. ++ points during Lisp evaluation --- never during redisplay. + (2) Accessibility elements are owned by EmacsView which belongs to + an active frame; windows referenced here are always reachable + from the frame's window tree until rebuildAccessibilityTree @@ -81,7 +81,7 @@ index ea6e7ba4f5..f245675513 100644 + NSUInteger ax_length; /* Length in accessibility string (UTF-16 units). */ +} ns_ax_visible_run; + -+/* Virtual AXTextArea element — one per visible Emacs window (buffer). */ ++/* Virtual AXTextArea element --- one per visible Emacs window (buffer). */ +@interface EmacsAccessibilityBuffer + : EmacsAccessibilityElement +{ @@ -119,7 +119,7 @@ index ea6e7ba4f5..f245675513 100644 +- (void)invalidateInteractiveSpans; +@end + -+/* Virtual AXStaticText element — one per mode line. */ ++/* Virtual AXStaticText element --- one per mode line. */ +@interface EmacsAccessibilityModeLine : EmacsAccessibilityElement +@end + @@ -294,7 +294,7 @@ index 88c9251c18..3b923ee5fa 100644 + + /* Extract this visible run's text. Use + Fbuffer_substring_no_properties which correctly handles the -+ buffer gap — raw BUF_BYTE_ADDRESS reads across the gap would ++ buffer gap --- raw BUF_BYTE_ADDRESS reads across the gap would + include garbage bytes when the run spans the gap position. */ + Lisp_Object lstr = Fbuffer_substring_no_properties ( + make_fixnum (pos), make_fixnum (run_end)); @@ -375,7 +375,7 @@ index 88c9251c18..3b923ee5fa 100644 + return NSZeroRect; + + /* charpos_start and charpos_len are already in buffer charpos -+ space — the caller maps AX string indices through ++ space --- the caller maps AX string indices through + charposForAccessibilityIndex which handles invisible text. */ + ptrdiff_t cp_start = charpos_start; + ptrdiff_t cp_end = cp_start + charpos_len; diff --git a/patches/0002-ns-implement-buffer-accessibility-element-core-proto.patch b/patches/0002-ns-implement-buffer-accessibility-element-core-proto.patch index 98e09bb..4b6fe97 100644 --- a/patches/0002-ns-implement-buffer-accessibility-element-core-proto.patch +++ b/patches/0002-ns-implement-buffer-accessibility-element-core-proto.patch @@ -358,7 +358,7 @@ index 3b923ee5fa..41c6b8dc14 100644 + NSTRACE ("EmacsAccessibilityBuffer ensureTextCache"); + /* This method is only called from the main thread (AX getters + dispatch_sync to main first). Reads of cachedText/cachedTextModiff -+ below are therefore safe without @synchronized — only the ++ below are therefore safe without @synchronized --- only the + write section at the end needs synchronization to protect + against concurrent reads from AX server thread. */ + eassert ([NSThread isMainThread]); @@ -473,7 +473,7 @@ index 3b923ee5fa..41c6b8dc14 100644 + /* Binary search: runs are sorted by charpos (ascending). Find the + run whose [charpos, charpos+length) range contains the target, + or the nearest run after an invisible gap. O(log n) instead of -+ O(n) — matters for org-mode with many folded sections. */ ++ O(n) --- matters for org-mode with many folded sections. */ + NSUInteger lo = 0, hi = visibleRunCount; + while (lo < hi) + { @@ -522,10 +522,10 @@ index 3b923ee5fa..41c6b8dc14 100644 + +/* Convert accessibility string index to buffer charpos. + Safe to call from any thread: uses only cachedText (NSString) and -+ visibleRuns — no Lisp calls. */ ++ visibleRuns --- no Lisp calls. */ +- (ptrdiff_t)charposForAccessibilityIndex:(NSUInteger)ax_idx +{ -+ /* May be called from AX server thread — synchronize. */ ++ /* May be called from AX server thread --- synchronize. */ + @synchronized (self) + { + if (visibleRunCount == 0) @@ -567,7 +567,7 @@ index 3b923ee5fa..41c6b8dc14 100644 + return cp; + } + } -+ /* Past end — return last charpos. */ ++ /* Past end --- return last charpos. */ + if (lo > 0) + { + ns_ax_visible_run *last = &visibleRuns[visibleRunCount - 1]; @@ -589,7 +589,7 @@ index 3b923ee5fa..41c6b8dc14 100644 + deadlocking the AX server thread. This is prevented by: + + 1. validWindow checks WINDOW_LIVE_P and BUFFERP before every -+ Lisp access — the window and buffer are verified live. ++ Lisp access --- the window and buffer are verified live. + 2. All dispatch_sync blocks run on the main thread where no + concurrent Lisp code can modify state between checks. + 3. block_input prevents timer events and process output from diff --git a/patches/0003-ns-add-buffer-notification-dispatch-and-mode-line-el.patch b/patches/0003-ns-add-buffer-notification-dispatch-and-mode-line-el.patch index 40f6c09..bcf5221 100644 --- a/patches/0003-ns-add-buffer-notification-dispatch-and-mode-line-el.patch +++ b/patches/0003-ns-add-buffer-notification-dispatch-and-mode-line-el.patch @@ -36,7 +36,7 @@ index 41c6b8dc14..16343f978a 100644 + + +/* =================================================================== -+ EmacsAccessibilityBuffer (Notifications) — AX event dispatch ++ EmacsAccessibilityBuffer (Notifications) --- AX event dispatch + + These methods notify VoiceOver of text and selection changes. + Called from the redisplay cycle (postAccessibilityUpdates). @@ -51,7 +51,7 @@ index 41c6b8dc14..16343f978a 100644 + if (point > self.cachedPoint + && point - self.cachedPoint == 1) + { -+ /* Single char inserted — refresh cache and grab it. */ ++ /* Single char inserted --- refresh cache and grab it. */ + [self invalidateTextCache]; + [self ensureTextCache]; + if (cachedText) @@ -70,7 +70,7 @@ index 41c6b8dc14..16343f978a 100644 + /* Update cachedPoint here so the selection-move branch does NOT + fire for point changes caused by edits. WebKit and Chromium + never send both ValueChanged and SelectedTextChanged for the -+ same user action — they are mutually exclusive. */ ++ same user action --- they are mutually exclusive. */ + self.cachedPoint = point; + + NSDictionary *change = @{ @@ -281,8 +281,8 @@ index 41c6b8dc14..16343f978a 100644 + ptrdiff_t currentOverlayStart = 0; + ptrdiff_t currentOverlayEnd = 0; + -+ block_input (); + specpdl_ref count2 = SPECPDL_INDEX (); ++ block_input (); + record_unwind_protect_void (unblock_input); + record_unwind_current_buffer (); + if (b != current_buffer) @@ -471,7 +471,7 @@ index 41c6b8dc14..16343f978a 100644 + } + + /* --- Cursor moved or selection changed --- -+ Use 'else if' — edits and selection moves are mutually exclusive ++ Use 'else if' --- edits and selection moves are mutually exclusive + per the WebKit/Chromium pattern. */ + else if (point != self.cachedPoint || markActive != self.cachedMarkActive) + { diff --git a/patches/0005-ns-integrate-accessibility-with-EmacsView-and-redisp.patch b/patches/0005-ns-integrate-accessibility-with-EmacsView-and-redisp.patch index 45c839d..5c24059 100644 --- a/patches/0005-ns-integrate-accessibility-with-EmacsView-and-redisp.patch +++ b/patches/0005-ns-integrate-accessibility-with-EmacsView-and-redisp.patch @@ -164,7 +164,7 @@ index f5e5cea074..c3cd83b774 100644 - /* =================================================================== - EmacsAccessibilityBuffer (Notifications) — AX event dispatch + EmacsAccessibilityBuffer (Notifications) --- AX event dispatch @@ -9283,6 +9332,54 @@ - (void)postAccessibilityNotificationsForFrame:(struct frame *)f granularity = ns_ax_text_selection_granularity_line; @@ -290,7 +290,7 @@ index f5e5cea074..c3cd83b774 100644 + + if (WINDOW_LEAF_P (w)) + { -+ /* Buffer element — reuse existing if available. */ ++ /* Buffer element --- reuse existing if available. */ + EmacsAccessibilityBuffer *elem + = [existing objectForKey:[NSValue valueWithPointer:w]]; + if (!elem) @@ -324,7 +324,7 @@ index f5e5cea074..c3cd83b774 100644 + } + else + { -+ /* Internal (combination) window — recurse into children. */ ++ /* Internal (combination) window --- recurse into children. */ + Lisp_Object child = w->contents; + while (!NILP (child)) + { @@ -436,7 +436,7 @@ index f5e5cea074..c3cd83b774 100644 + accessibilityUpdating = YES; + + /* Detect window tree change (split, delete, new buffer). Compare -+ FRAME_ROOT_WINDOW — if it changed, the tree structure changed. */ ++ FRAME_ROOT_WINDOW --- if it changed, the tree structure changed. */ + Lisp_Object curRoot = FRAME_ROOT_WINDOW (emacsframe); + if (!EQ (curRoot, lastRootWindow)) + { @@ -445,12 +445,12 @@ index f5e5cea074..c3cd83b774 100644 + } + + /* If tree is stale, rebuild FIRST so we don't iterate freed -+ window pointers. Skip notifications for this cycle — the ++ window pointers. Skip notifications for this cycle --- the + freshly-built elements have no previous state to diff against. */ + if (!accessibilityTreeValid) + { + [self rebuildAccessibilityTree]; -+ /* Invalidate span cache — window layout changed. */ ++ /* Invalidate span cache --- window layout changed. */ + for (EmacsAccessibilityElement *elem in accessibilityElements) + if ([elem isKindOfClass: [EmacsAccessibilityBuffer class]]) + [(EmacsAccessibilityBuffer *) elem invalidateInteractiveSpans]; diff --git a/patches/0007-ns-announce-overlay-completion-candidates-for-VoiceO.patch b/patches/0007-ns-announce-overlay-completion-candidates-for-VoiceO.patch index c1374ea..b4db169 100644 --- a/patches/0007-ns-announce-overlay-completion-candidates-for-VoiceO.patch +++ b/patches/0007-ns-announce-overlay-completion-candidates-for-VoiceO.patch @@ -209,7 +209,7 @@ index e4e43dd7a3..c9fe93a57b 100644 /* Extract this visible run's text. Use Fbuffer_substring_no_properties which correctly handles the -- buffer gap — raw BUF_BYTE_ADDRESS reads across the gap would +- buffer gap --- raw BUF_BYTE_ADDRESS reads across the gap would + buffer gap --- raw BUF_BYTE_ADDRESS reads across the gap would include garbage bytes when the run spans the gap position. */ Lisp_Object lstr = Fbuffer_substring_no_properties ( @@ -218,7 +218,7 @@ index e4e43dd7a3..c9fe93a57b 100644 return NSZeroRect; /* charpos_start and charpos_len are already in buffer charpos -- space — the caller maps AX string indices through +- space --- the caller maps AX string indices through + space --- the caller maps AX string indices through charposForAccessibilityIndex which handles invisible text. */ ptrdiff_t cp_start = charpos_start; @@ -267,7 +267,7 @@ index e4e43dd7a3..c9fe93a57b 100644 NSTRACE ("EmacsAccessibilityBuffer ensureTextCache"); /* This method is only called from the main thread (AX getters dispatch_sync to main first). Reads of cachedText/cachedTextModiff -- below are therefore safe without @synchronized — only the +- below are therefore safe without @synchronized --- only the + below are therefore safe without @synchronized --- only the write section at the end needs synchronization to protect against concurrent reads from AX server thread. */ @@ -354,7 +354,7 @@ index e4e43dd7a3..c9fe93a57b 100644 /* Binary search: runs are sorted by charpos (ascending). Find the run whose [charpos, charpos+length) range contains the target, or the nearest run after an invisible gap. O(log n) instead of -- O(n) — matters for org-mode with many folded sections. */ +- O(n) --- matters for org-mode with many folded sections. */ + O(n) --- matters for org-mode with many folded sections. */ NSUInteger lo = 0, hi = visibleRunCount; while (lo < hi) @@ -363,11 +363,11 @@ index e4e43dd7a3..c9fe93a57b 100644 /* Convert accessibility string index to buffer charpos. Safe to call from any thread: uses only cachedText (NSString) and -- visibleRuns — no Lisp calls. */ +- visibleRuns --- no Lisp calls. */ + visibleRuns --- no Lisp calls. */ - (ptrdiff_t)charposForAccessibilityIndex:(NSUInteger)ax_idx { -- /* May be called from AX server thread — synchronize. */ +- /* May be called from AX server thread --- synchronize. */ + /* May be called from AX server thread --- synchronize. */ @synchronized (self) { @@ -376,7 +376,7 @@ index e4e43dd7a3..c9fe93a57b 100644 return cp; } } -- /* Past end — return last charpos. */ +- /* Past end --- return last charpos. */ + /* Past end --- return last charpos. */ if (lo > 0) { @@ -385,7 +385,7 @@ index e4e43dd7a3..c9fe93a57b 100644 deadlocking the AX server thread. This is prevented by: 1. validWindow checks WINDOW_LIVE_P and BUFFERP before every -- Lisp access — the window and buffer are verified live. +- Lisp access --- the window and buffer are verified live. + Lisp access --- the window and buffer are verified live. 2. All dispatch_sync blocks run on the main thread where no concurrent Lisp code can modify state between checks. @@ -462,7 +462,7 @@ index e4e43dd7a3..c9fe93a57b 100644 /* =================================================================== -- EmacsAccessibilityBuffer (Notifications) — AX event dispatch +- EmacsAccessibilityBuffer (Notifications) --- AX event dispatch + EmacsAccessibilityBuffer (Notifications) --- AX event dispatch These methods notify VoiceOver of text and selection changes. @@ -471,7 +471,7 @@ index e4e43dd7a3..c9fe93a57b 100644 if (point > self.cachedPoint && point - self.cachedPoint == 1) { -- /* Single char inserted — refresh cache and grab it. */ +- /* Single char inserted --- refresh cache and grab it. */ + /* Single char inserted --- refresh cache and grab it. */ [self invalidateTextCache]; [self ensureTextCache]; @@ -480,7 +480,7 @@ index e4e43dd7a3..c9fe93a57b 100644 /* Update cachedPoint here so the selection-move branch does NOT fire for point changes caused by edits. WebKit and Chromium never send both ValueChanged and SelectedTextChanged for the -- same user action — they are mutually exclusive. */ +- same user action --- they are mutually exclusive. */ + same user action --- they are mutually exclusive. */ self.cachedPoint = point; @@ -562,7 +562,7 @@ index e4e43dd7a3..c9fe93a57b 100644 } /* --- Cursor moved or selection changed --- -- Use 'else if' — edits and selection moves are mutually exclusive +- Use 'else if' --- edits and selection moves are mutually exclusive - per the WebKit/Chromium pattern. */ - else if (point != self.cachedPoint || markActive != self.cachedMarkActive) + Independent check from the overlay branch above. */ @@ -590,7 +590,7 @@ index e4e43dd7a3..c9fe93a57b 100644 if (WINDOW_LEAF_P (w)) { -- /* Buffer element — reuse existing if available. */ +- /* Buffer element --- reuse existing if available. */ + /* Buffer element --- reuse existing if available. */ EmacsAccessibilityBuffer *elem = [existing objectForKey:[NSValue valueWithPointer:w]]; @@ -599,7 +599,7 @@ index e4e43dd7a3..c9fe93a57b 100644 } else { -- /* Internal (combination) window — recurse into children. */ +- /* Internal (combination) window --- recurse into children. */ + /* Internal (combination) window --- recurse into children. */ Lisp_Object child = w->contents; while (!NILP (child)) @@ -608,7 +608,7 @@ index e4e43dd7a3..c9fe93a57b 100644 accessibilityUpdating = YES; /* Detect window tree change (split, delete, new buffer). Compare -- FRAME_ROOT_WINDOW — if it changed, the tree structure changed. */ +- FRAME_ROOT_WINDOW --- if it changed, the tree structure changed. */ + FRAME_ROOT_WINDOW --- if it changed, the tree structure changed. */ Lisp_Object curRoot = FRAME_ROOT_WINDOW (emacsframe); if (!EQ (curRoot, lastRootWindow)) @@ -617,13 +617,13 @@ index e4e43dd7a3..c9fe93a57b 100644 } /* If tree is stale, rebuild FIRST so we don't iterate freed -- window pointers. Skip notifications for this cycle — the +- window pointers. Skip notifications for this cycle --- the + window pointers. Skip notifications for this cycle --- the freshly-built elements have no previous state to diff against. */ if (!accessibilityTreeValid) { [self rebuildAccessibilityTree]; -- /* Invalidate span cache — window layout changed. */ +- /* Invalidate span cache --- window layout changed. */ + /* Invalidate span cache --- window layout changed. */ for (EmacsAccessibilityElement *elem in accessibilityElements) if ([elem isKindOfClass: [EmacsAccessibilityBuffer class]])