Subject: bug#10994: closed (Re: bug#10994: 23.3; ido-mode: ido-next-match / ido-prev-match work wrong with same elements)

From: [email-masked] (GNU bug Tracking System)
Date: Wed, 20 Mar 2013 03:14:02 +0000

Your bug report

#10994: 23.3; ido-mode: ido-next-match / ido-prev-match work wrong with same elements

which was filed against the emacs package, has been closed.

The explanation is attached below, along with your original report.
If you require more details, please reply to [email-masked].

-- 
10994: http://debbugs.gnu.org/cgi/bugreport.cgi?bug=10994
GNU Bug Tracking System
Contact [email-masked] with problems

Subject: Re: bug#10994: 23.3; ido-mode: ido-next-match / ido-prev-match work wrong with same elements
From: Leo Liu <[email-masked]>
To: Anonymous <[email-masked]>
Cc: [email-masked]
Date: Wed, 20 Mar 2013 11:11:27 +0800
List-Id: <debbugs-submit.debbugs.gnu.org>

Fixed in 24.4.

Patch seems working in my tests. So close the bug.

Leo

Subject: 23.3; ido-mode: ido-next-match / ido-prev-match work wrong with same elements
From: Anonymous <[email-masked]>
To: [email-masked]
Date: Sun, 11 Mar 2012 14:33:48 +0200
List-Id: <debbugs-submit.debbugs.gnu.org>

Recipe:
(require 'ido)
(ido-completing-read "dat is whrong -> " '("2" "3" "3" "3" "4" "5"))
Browse this with C-s and C-r. C-s will stuck, C-r will jump to the first occurence of "3".

I've managed to fix this.
In ido-chop:
 first, we don't need to choose the first element.
 second, we should supply backward-move, to search in reverse. In this way, we find "last" element, as it shold really be.
I did not fix all the functions, that use ido-chop, however. Here is the example with ido-prev-match.

(defun ido-chop (items elem &optional backward-move)
  "Remove all elements before ELEM and put them at the end of ITEMS."
  (let ((ret nil)
         (next nil)
         (sofar nil))
    (progn
      (setq next (car items))
      (setq items (cdr items))
      (setq sofar (cons next sofar)))
    (when backward-move
      (setq items (nreverse items)))
    (while (not ret)
      (setq next (car items))
      (if (equal next elem)
        (progn
          (when backward-move
            (setq next (car items))
            (setq items (cdr items))
            (setq sofar (cons next sofar)))
          (setq ret (append items (nreverse sofar))))
        ;; else
        (progn
          (setq items (cdr items))
          (setq sofar (cons next sofar)))))
    (if backward-move (nreverse ret) ret)))

(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 t))
      (setq ido-matches (ido-chop ido-matches prev t))
      (setq ido-rescan nil))))