branch: elpa/recomplete
commit c0b1a38cceb3cd65c8e6004f527eba293caafeef
Author: Campbell Barton <[email protected]>
Commit: Campbell Barton <[email protected]>

    Fix: cycling broken when recomplete-single-line-display is nil
    
    The message display, state saving, and post-command-hook setup were
    nested inside (when recomplete-single-line-display ...), so cycling
    only worked when this option was enabled. Move these outside the
    `when` block so only the single-line truncation logic is gated.
---
 recomplete.el            | 48 ++++++++++++++++++++++++------------------------
 tests/recomplete-test.el | 44 ++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 68 insertions(+), 24 deletions(-)

diff --git a/recomplete.el b/recomplete.el
index 4f925c8014..9e3e28409b 100644
--- a/recomplete.el
+++ b/recomplete.el
@@ -689,30 +689,30 @@ step onto the next item)."
                           (truncate-string-to-width msg-text msg-end msg-start 
0 ellipsis))
 
                     (unless (zerop msg-start)
-                      (setq msg-text (concat ellipsis (substring msg-text 
(length ellipsis)))))))))
-            ;; Single line display logic has been handled.
-
-            ;; Run last so we can ensure it's the last text in the message 
buffer.
-            ;; Don't log because it's not useful to keep the selection.
-            (let ((message-log-max nil))
-              (message "%s%s" msg-prefix msg-text))
-
-            ;; Set the state for redoing the correction.
-            (setq recomplete--alist
-                  (list
-                   (cons 'buffer-undo-list buffer-undo-list-init)
-                   (cons 'pending-undo-list pending-undo-list-init)
-                   (cons 'point point-init)
-                   (cons 'cycle-index cycle-index)
-                   (cons 'cycle-reverse cycle-reverse)
-                   (cons 'fn-symbol fn-symbol)
-                   (cons 'fn-cache result-fn-cache)
-                   (cons 'is-first-post-command t)
-                   (cons 'msg-text msg-text)))
-
-            ;; Ensure a local hook, which removes itself on the first 
non-successive call
-            ;; to a command that doesn't execute `recomplete-with-callback' 
with `fn-symbol'.
-            (add-hook 'post-command-hook #'recomplete--alist-clear-hook 0 t)))
+                      (setq msg-text
+                            (concat ellipsis (substring msg-text (length 
ellipsis))))))))))
+
+          ;; Run last so we can ensure it's the last text in the message 
buffer.
+          ;; Don't log because it's not useful to keep the selection.
+          (let ((message-log-max nil))
+            (message "%s%s" msg-prefix msg-text))
+
+          ;; Set the state for redoing the correction.
+          (setq recomplete--alist
+                (list
+                 (cons 'buffer-undo-list buffer-undo-list-init)
+                 (cons 'pending-undo-list pending-undo-list-init)
+                 (cons 'point point-init)
+                 (cons 'cycle-index cycle-index)
+                 (cons 'cycle-reverse cycle-reverse)
+                 (cons 'fn-symbol fn-symbol)
+                 (cons 'fn-cache result-fn-cache)
+                 (cons 'is-first-post-command t)
+                 (cons 'msg-text msg-text)))
+
+          ;; Ensure a local hook, which removes itself on the first 
non-successive call
+          ;; to a command that doesn't execute `recomplete-with-callback' with 
`fn-symbol'.
+          (add-hook 'post-command-hook #'recomplete--alist-clear-hook 0 t))
 
         ;; Result, success.
         t)))))
diff --git a/tests/recomplete-test.el b/tests/recomplete-test.el
index f75abe715e..47876e22c3 100644
--- a/tests/recomplete-test.el
+++ b/tests/recomplete-test.el
@@ -121,6 +121,50 @@
  "pre completion post"
  (cons 7 8))
 
+;; ---------------------------------------------------------------------------
+;; Test Cycling Utilities
+
+(defmacro simulate-input (&rest keys)
+  "Helper macro to simulate input using KEYS."
+  (declare (indent 0))
+  `(let ((keys-list (list ,@keys)))
+     (dolist (keys keys-list)
+       (let ((minibuffer-message-timeout 0))
+         (execute-kbd-macro keys)))))
+
+(defun buffer-reset-text (initial-buffer-text)
+  "Use INITIAL-BUFFER-TEXT to initialize the buffer with text."
+  (buffer-disable-undo)
+  (erase-buffer)
+  (save-excursion (insert initial-buffer-text))
+  (buffer-enable-undo))
+
+;; ---------------------------------------------------------------------------
+;; Test Cycling
+
+(ert-deftest dabbrev-cycling-single-line-display-nil ()
+  "Dabbrev cycling should work when `recomplete-single-line-display' is nil.
+Without cycling, the second press tries to expand the already-expanded word
+which has no further expansions, causing an error."
+  (let ((buf (generate-new-buffer "recomplete-test")))
+    (switch-to-buffer buf)
+    (buffer-reset-text "unique_alpha unique_beta un")
+    (goto-char (point-max))
+    (let ((recomplete-single-line-display nil)
+          (inhibit-message t))
+      (local-set-key (kbd "M-p") #'recomplete-dabbrev)
+      ;; Press M-p twice to cycle to the second expansion.
+      (simulate-input
+        (kbd "M-p M-p"))
+      ;; With cycling: "un" expands to "unique_beta", then cycles to 
"unique_alpha".
+      ;; Without cycling (bug): "un" expands to "unique_beta", then a fresh
+      ;; expand of "unique_beta" finds no new expansions and errors.
+      (should
+       (equal
+        "unique_alpha unique_beta unique_alpha"
+        (buffer-substring-no-properties (point-min) (point-max)))))
+    (kill-buffer buf)))
+
 
 (provide 'recomplete-test)
 ;; Local Variables:

Reply via email to