Files
emacs-doom/patches/0009-ns-fix-overlay-candidate-detection.patch

153 lines
4.8 KiB
Diff

From 2e5505f044e403ccaef8c43bdc66480c71dcf05a Mon Sep 17 00:00:00 2001
From: Martin Sukany <martin@sukany.cz>
Date: Sat, 28 Feb 2026 14:44:37 +0100
Subject: [PATCH] ns: fix overlay candidate detection (Fequal face comparison)
The previous ns_ax_selected_overlay_text matched ANY non-nil face,
but all Vertico lines have faces. Fix: collect line boundaries,
compare each line's face against the first line's face via Fequal,
return the line with a DIFFERENT face (the selected candidate).
Also fix duplicate 'NSString *candidate' declaration.
* src/nsterm.m (ns_ax_selected_overlay_text): Rewrite to compare
faces line-by-line via Fequal instead of matching first non-nil face.
---
src/nsterm.m | 94 +++++++++++++++++++++++++++-------------------------
1 file changed, 48 insertions(+), 46 deletions(-)
diff --git a/src/nsterm.m b/src/nsterm.m
index 43d30f9..35edd39 100644
--- a/src/nsterm.m
+++ b/src/nsterm.m
@@ -6916,12 +6916,12 @@ ns_create_font_panel_buttons (id target, SEL select, SEL cancel_action)
#define NS_AX_TEXT_CAP 100000
/* Extract the currently selected candidate text from overlay display
- strings in window W. Completion frameworks (Vertico, Ivy, Icomplete)
- highlight the current candidate by applying a face property to a
- portion of the overlay's before-string or after-string. We find
- that highlighted portion and return it as an NSString.
+ strings. Completion frameworks (Vertico, Ivy, Icomplete) highlight
+ the current candidate with a distinct face. We find the line whose
+ face DIFFERS from the first line's face (the "normal" candidate
+ face) — that is the selected candidate.
- Returns nil if no highlighted overlay text is found. */
+ Returns nil if no distinctly-faced line is found. */
static NSString *
ns_ax_selected_overlay_text (struct buffer *b,
ptrdiff_t beg, ptrdiff_t end)
@@ -6942,57 +6942,60 @@ ns_ax_selected_overlay_text (struct buffer *b,
continue;
Lisp_Object str = strings[s];
- ptrdiff_t len = SCHARS (str);
- ptrdiff_t pos = 0;
+ ptrdiff_t slen = SCHARS (str);
+ if (slen == 0)
+ continue;
+
+ /* Collect line boundaries. */
+ ptrdiff_t line_starts[512];
+ ptrdiff_t line_ends[512];
+ int nlines = 0;
+ ptrdiff_t lstart = 0;
- while (pos < len)
+ for (ptrdiff_t i = 0; i <= slen && nlines < 512; i++)
{
- Lisp_Object face
- = Fget_text_property (make_fixnum (pos),
- Qface, str);
- if (!NILP (face))
+ bool is_nl = false;
+ if (i < slen)
+ {
+ Lisp_Object ch = Faref (str, make_fixnum (i));
+ is_nl = (FIXNUMP (ch) && XFIXNUM (ch) == '\n');
+ }
+ if (is_nl || i == slen)
{
- /* Found highlighted text. Extract the full line
- containing this position. */
- ptrdiff_t line_start = pos;
- while (line_start > 0)
+ if (i > lstart)
{
- /* Check character before line_start. */
- Lisp_Object ch
- = Faref (str, make_fixnum (line_start - 1));
- if (FIXNUMP (ch) && XFIXNUM (ch) == '\n')
- break;
- line_start--;
+ line_starts[nlines] = lstart;
+ line_ends[nlines] = i;
+ nlines++;
}
+ lstart = i + 1;
+ }
+ }
- ptrdiff_t line_end = pos;
- while (line_end < len)
- {
- Lisp_Object ch
- = Faref (str, make_fixnum (line_end));
- if (FIXNUMP (ch) && XFIXNUM (ch) == '\n')
- break;
- line_end++;
- }
+ if (nlines < 2)
+ continue;
+ /* Get the face of the first line (the "normal" face). */
+ Lisp_Object normal_face
+ = Fget_text_property (make_fixnum (line_starts[0]),
+ Qface, str);
+
+ /* Find the first line with a DIFFERENT face. */
+ for (int li = 0; li < nlines; li++)
+ {
+ Lisp_Object line_face
+ = Fget_text_property (make_fixnum (line_starts[li]),
+ Qface, str);
+ if (NILP (Fequal (line_face, normal_face)))
+ {
Lisp_Object line
- = Fsubstring_no_properties (str,
- make_fixnum (line_start),
- make_fixnum (line_end));
+ = Fsubstring_no_properties (
+ str,
+ make_fixnum (line_starts[li]),
+ make_fixnum (line_ends[li]));
if (SCHARS (line) > 0)
return [NSString stringWithLispString:line];
}
-
- /* Skip to next face change. */
- Lisp_Object next
- = Fnext_single_property_change (make_fixnum (pos),
- Qface, str,
- make_fixnum (len));
- ptrdiff_t npos
- = FIXNUMP (next) ? XFIXNUM (next) : len;
- if (npos <= pos)
- break;
- pos = npos;
}
}
}
@@ -8956,7 +8959,6 @@ ns_ax_completion_text_for_span (EmacsAccessibilityBuffer *elem,
properties. Completion frameworks highlight the current
candidate with a text face (e.g. vertico-current,
icomplete-selected-match). */
- NSString *candidate
NSString *candidate
= ns_ax_selected_overlay_text (b, BUF_BEGV (b), BUF_ZV (b));
if (candidate)
--
2.43.0