153 lines
4.8 KiB
Diff
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
|
|
|