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 ae1c7d6451f5a6be397f50c314e03b43b4e47b5c Mon Sep 17 00:00:00 2001
From 7aab25d3ba9b41d3d81693b04d8d74812cad9139 Mon Sep 17 00:00:00 2001
From: Martin Sukany <martin@sukany.cz>
Date: Sat, 28 Feb 2026 12:58:11 +0100
Subject: [PATCH 5/8] ns: integrate accessibility with EmacsView and redisplay
@@ -51,7 +51,7 @@ index 80661a9..2b1f9e6 100644
** Re-introduced dictation, lost in Emacs v30 (macOS).
We lost macOS dictation in v30 when migrating to NSTextInputClient.
diff --git a/src/nsterm.m b/src/nsterm.m
index 98ff027..0a70f3e 100644
index 94a4602..51813b5 100644
--- a/src/nsterm.m
+++ b/src/nsterm.m
@@ -1258,7 +1258,7 @@ If a completion candidate is selected (overlay or child frame),
@@ -157,7 +157,7 @@ index 98ff027..0a70f3e 100644
static BOOL
ns_ax_find_completion_overlay_range (struct buffer *b, ptrdiff_t point,
ptrdiff_t *out_start,
@@ -8727,7 +8777,6 @@ - (NSRect)accessibilityFrame
@@ -8743,7 +8793,6 @@ - (NSRect)accessibilityFrame
@end
@@ -165,7 +165,7 @@ index 98ff027..0a70f3e 100644
/* ===================================================================
EmacsAccessibilityBuffer (Notifications) — AX event dispatch
@@ -9272,7 +9321,6 @@ - (NSRect)accessibilityFrame
@@ -9288,7 +9337,6 @@ - (NSRect)accessibilityFrame
@end
@@ -173,7 +173,7 @@ index 98ff027..0a70f3e 100644
/* ===================================================================
EmacsAccessibilityInteractiveSpan — helpers and implementation
=================================================================== */
@@ -9602,6 +9650,7 @@ - (void)dealloc
@@ -9618,6 +9666,7 @@ - (void)dealloc
[layer release];
#endif
@@ -181,7 +181,7 @@ index 98ff027..0a70f3e 100644
[[self menu] release];
[super dealloc];
}
@@ -10950,6 +10999,32 @@ - (void)windowDidBecomeKey /* for direct calls */
@@ -10966,6 +11015,32 @@ - (void)windowDidBecomeKey /* for direct calls */
XSETFRAME (event.frame_or_window, emacsframe);
kbd_buffer_store_event (&event);
ns_send_appdefined (-1); // Kick main loop
@@ -214,7 +214,7 @@ index 98ff027..0a70f3e 100644
}
@@ -12187,6 +12262,332 @@ - (int) fullscreenState
@@ -12203,6 +12278,332 @@ - (int) fullscreenState
return fs_state;
}
@@ -547,7 +547,7 @@ index 98ff027..0a70f3e 100644
@end /* EmacsView */
@@ -14187,12 +14588,17 @@ Nil means use fullscreen the old (< 10.7) way. The old way works better with
@@ -14203,12 +14604,17 @@ Nil means use fullscreen the old (< 10.7) way. The old way works better with
ns_use_srgb_colorspace = YES;
DEFVAR_BOOL ("ns-accessibility-enabled", ns_accessibility_enabled,