Subject: Re: bug#68688: 30.0.50; next-line-completion doesn't work with multiline completions

From: Spencer Baugh <[email-masked]>
Date: Wed, 24 Jan 2024 10:55:37 -0500

Patch which fixes this attached.  It simply adds an additional loop
around forward-line which runs until we leave the completion at point.

BTW, I think we should have some helper functions for "get start of
completion candidate or point-min" and "get end of completion candidate
or point-max", or possibly "move to start of candidate" and "move to end
of candidate"; it's pretty hard to get right.

>From ffe03b3fe8fb805f5e4eb0a2ea956d573272e74a Mon Sep 17 00:00:00 2001
From: Spencer Baugh <[email-masked]>
Date: Wed, 24 Jan 2024 10:52:40 -0500
Subject: [PATCH] Fix next-line-completion for multi-line completions

Previously it would not move out of a multi-line completion, and now it will.

* lisp/simple.el (next-line-completion): Move out of the completion
before going forward lines.  (bug#68688)
---
 lisp/simple.el | 20 ++++++++++++++++++++
 1 file changed, 20 insertions(+)

diff --git a/lisp/simple.el b/lisp/simple.el
index 313241a7d34..35fd76b8d1a 100644
--- a/lisp/simple.el
+++ b/lisp/simple.el
@@ -9937,6 +9937,17 @@ next-line-completion
 
     (while (> n 0)
       (setq found nil pos nil column (current-column) line (line-number-at-pos))
+      ;; If in a completion and not at the end, move lines forward
+      ;; until we leave it or reach the end.
+      (when (and (get-text-property (point) 'mouse-face)
+                 (not (eobp))
+                 (get-text-property (1+ (point)) 'mouse-face))
+        (let ((end (or (next-single-property-change (point) 'mouse-face) (point-max))))
+          (while (and
+                  (< (point) end)
+                  (eq (forward-line 1) 0)
+                  (not (eobp))
+                  (eq (move-to-column column) column)))))
       (while (and (not found)
                   (eq (forward-line 1) 0)
                   (not (eobp))
@@ -9961,6 +9972,15 @@ next-line-completion
 
     (while (< n 0)
       (setq found nil pos nil column (current-column) line (line-number-at-pos))
+      ;; If in a completion and not at the start, move lines backward
+      ;; until we leave it or reach the start.
+      (when (and (get-text-property (point) 'mouse-face)
+                 (not (bobp))
+                 (get-text-property (1- (point)) 'mouse-face))
+        (let ((start (previous-single-property-change (point) 'mouse-face)))
+          (while (and (> (point) start)
+                      (eq (forward-line -1) 0)
+                      (eq (move-to-column column) column)))))
       (while (and (not found)
                   (eq (forward-line -1) 0)
                   (eq (move-to-column column) column))
-- 
2.39.3