Subject: bug#5724: 23.1.94; ido bug in next match

From: Leo <[email-masked]>
Date: Sat, 27 Mar 2010 10:43:16 +0000

On 2010-03-26 09:40 +0000, Christian Dietrich wrote:
> Hi,
> i can reproduce your bug here with emacs 23.1, and i tried to track
> down the problem. But as far as i can see the reordering of the
> match results isn't done by ido-set-matches-1. The position of the
> matches items in ido-cur-list and in the result of ido-set-matches-1
> is the same. Think of 
>
> (remove-if '(lambda (x) (not (member x after-match)) before-match)
>
> So i assume that the Problem isn't at that place.
>
> greetz didi

I think I have located the problem.

ido-set-matches is called with different args when C-s so it returns
different matches. I couldn't understand why it is designed this way. I
am surprised no one has been annoyed by this bug. It has caused me to
choose the wrong match quite often. I have attempted a fix by simply
rotating the ido-matches when rotating.

diff --git a/lisp/ido.el b/lisp/ido.el
index e414408..803fa74 100644
--- a/lisp/ido.el
+++ b/lisp/ido.el
@@ -3145,20 +3145,18 @@ If repeated, insert text from buffer instead."
 (defun ido-next-match ()
   "Put first element of `ido-matches' at the end of the list."
   (interactive)
-  (if ido-matches
-      (let ((next (cadr ido-matches)))
-	(setq ido-cur-list (ido-chop ido-cur-list next))
-	(setq ido-rescan t)
-	(setq ido-rotate t))))
+  (when ido-matches
+    (setq ido-matches
+          (ido-chop ido-matches (cadr ido-matches)))
+    (setq ido-rotate t)))
 
 (defun ido-prev-match ()
   "Put last element of `ido-matches' at the front of the list."
   (interactive)
-  (if ido-matches
-      (let ((prev (car (last ido-matches))))
-	(setq ido-cur-list (ido-chop ido-cur-list prev))
-	(setq ido-rescan t)
-	(setq ido-rotate t))))
+  (when ido-matches
+    (setq ido-matches
+          (ido-chop ido-matches (car (last ido-matches))))
+    (setq ido-rotate t)))
 
 (defun ido-next-match-dir ()
   "Find next directory in match list.
@@ -3177,7 +3175,8 @@ first matching file."
       (while (and (< i cnt) (not (ido-final-slash (nth i ido-matches))))
 	(setq i (1+ i)))
       (if (< i cnt)
-	  (setq ido-cur-list (ido-chop ido-cur-list (nth i ido-matches)))))))
+	  (setq ido-matches (ido-chop ido-matches (nth i ido-matches))
+                ido-rotate t)))))
 
 (defun ido-prev-match-dir ()
   "Find previous directory in match list.
@@ -3196,7 +3195,8 @@ for first matching file."
       (while (and (> i 0) (not (ido-final-slash (nth i ido-matches))))
 	(setq i (1- i)))
       (if (> i 0)
-	  (setq ido-cur-list (ido-chop ido-cur-list (nth i ido-matches)))))))
+	  (setq ido-matches (ido-chop ido-matches (nth i ido-matches))
+                ido-rotate t)))))
 
 (defun ido-restrict-to-matches ()
   "Set current item list to the currently matched items."
@@ -4494,8 +4494,10 @@ For details of keybindings, see `ido-find-file'."
 
 	;; Update the list of matches
 	(setq ido-text contents)
-	(ido-set-matches)
-	(ido-trace "new    " ido-matches)
+	(if ido-rotate
+            (setq ido-rotate nil)
+          (ido-set-matches)
+          (ido-trace "new    " ido-matches))
 
 	(when (and ido-enter-matching-directory
 		   ido-matches

Cheers,

Leo