patches: fix O(position) lag — O(1) fast path in accessibilityIndexForCharpos:

accessibilityIndexForCharpos: walked composed character sequences
from run.ax_start up to the target charpos offset.  For a run
covering an entire ASCII buffer, chars_in = pt - BUF_BEGV, making
each call O(cursor_position).

This method is called from ensureTextCache on EVERY redisplay frame
(as part of the cache validity check), making each frame O(position)
even when the buffer is completely unchanged.  At line 34,000 of a
large file this is ~1,000,000 iterations per frame.

Fix: when ax_length == length for a run (all single-unit characters),
the ax_index is simply ax_start + chars_in.  O(1) instead of O(N).

This is the symmetric counterpart to the charposForAccessibilityIndex:
fast path added in the previous commit.  Both conversion directions
now run in O(1) for pure-ASCII buffers.
This commit is contained in:
2026-03-01 09:14:52 +01:00
parent fb68dd50ea
commit 0c13f5d6a3
7 changed files with 94 additions and 51 deletions

View File

@@ -1,4 +1,4 @@
From 35a32f4802822ee77350a6d652aa45cca38e304c Mon Sep 17 00:00:00 2001
From fed3a06865d403db5d25074e7473c4d7c360f917 Mon Sep 17 00:00:00 2001
From: Martin Sukany <martin@sukany.cz>
Date: Sat, 28 Feb 2026 16:01:29 +0100
Subject: [PATCH 8/8] ns: announce child frame completion candidates for
@@ -109,7 +109,7 @@ index 2102fb9..dd98d56 100644
@end
diff --git a/src/nsterm.m b/src/nsterm.m
index c74eaf1..d2f88a5 100644
index 7ce683d..8a1316a 100644
--- a/src/nsterm.m
+++ b/src/nsterm.m
@@ -7398,6 +7398,112 @@ visual line index for Zoom (skip whitespace-only lines
@@ -268,7 +268,7 @@ index c74eaf1..d2f88a5 100644
cachedTextStart = start;
if (visibleRuns)
@@ -9143,6 +9258,7 @@ - (void)postCompletionAnnouncementForBuffer:(struct buffer *)b
@@ -9171,6 +9286,7 @@ - (void)postCompletionAnnouncementForBuffer:(struct buffer *)b
ptrdiff_t currentOverlayStart = 0;
ptrdiff_t currentOverlayEnd = 0;
@@ -276,7 +276,7 @@ index c74eaf1..d2f88a5 100644
specpdl_ref count2 = SPECPDL_INDEX ();
record_unwind_current_buffer ();
if (b != current_buffer)
@@ -9301,6 +9417,7 @@ - (void)postCompletionAnnouncementForBuffer:(struct buffer *)b
@@ -9329,6 +9445,7 @@ - (void)postCompletionAnnouncementForBuffer:(struct buffer *)b
self.cachedCompletionOverlayEnd = 0;
self.cachedCompletionPoint = 0;
}
@@ -284,7 +284,7 @@ index c74eaf1..d2f88a5 100644
}
/* ---- Notification dispatch (main entry point) ---- */
@@ -9897,6 +10014,10 @@ - (void)dealloc
@@ -9925,6 +10042,10 @@ - (void)dealloc
#endif
[accessibilityElements release];
@@ -295,7 +295,7 @@ index c74eaf1..d2f88a5 100644
[[self menu] release];
[super dealloc];
}
@@ -11346,6 +11467,9 @@ - (instancetype) initFrameFromEmacs: (struct frame *)f
@@ -11374,6 +11495,9 @@ - (instancetype) initFrameFromEmacs: (struct frame *)f
windowClosing = NO;
processingCompose = NO;
@@ -305,7 +305,7 @@ index c74eaf1..d2f88a5 100644
scrollbarsNeedingUpdate = 0;
fs_state = FULLSCREEN_NONE;
fs_before_fs = next_maximized = -1;
@@ -12654,6 +12778,80 @@ - (id)accessibilityFocusedUIElement
@@ -12682,6 +12806,80 @@ - (id)accessibilityFocusedUIElement
The existing elements carry cached state (modiff, point) from the
previous redisplay cycle. Rebuilding first would create fresh
elements with current values, making change detection impossible. */
@@ -386,7 +386,7 @@ index c74eaf1..d2f88a5 100644
- (void)postAccessibilityUpdates
{
NSTRACE ("[EmacsView postAccessibilityUpdates]");
@@ -12664,11 +12862,59 @@ - (void)postAccessibilityUpdates
@@ -12692,11 +12890,59 @@ - (void)postAccessibilityUpdates
/* Re-entrance guard: VoiceOver callbacks during notification posting
can trigger redisplay, which calls ns_update_end, which calls us