Subject: bug#8725: 23.2; imenu--split-menu should not deliver surprises

From: dino chiesa <[email-masked]>
Date: Tue, 24 May 2011 06:16:32 -0700

imenu--split-menu sorts the menu structure, placing breakout menus at
the top.  This seems arbitrary, surprising, and unnecessary.  
 
A reasonable sorting behavior would be to sort in the order in which the
menu items were found - that is to say, leave the order the way it was
on entry to the defun.  Another reasonable sorting behavior would be to
sort menu items lexicographically.  This defun does neither of those
things but rather applies the arbitrary decision to put items with
submenus at the top. Why?
 
This is not consistent with good UI design. It makes for a confusing
menu, in which the order of items doesn't correspond to *anything* useful.
 
Also, this behavior is not avoidable. Though imenu allows specification
of a sort function for menbu items, the arbitrary sorting described
above happens whether or not a custom sort function is provided. The
only way around this is to advise or redefine imenu--split-menu.
 
To fix this, in imenu.el , redefine imenu--split-menu to remove the offending
arbitrariness: 
 
    (defun imenu--split-menu (menulist title)
      (let ((menulist (copy-sequence menulist))
            keep-at-top tail)
        (if (memq imenu--rescan-item menulist)
            (setq keep-at-top (list imenu--rescan-item)
                  menulist (delq imenu--rescan-item menulist)))
        ;; DPC - ban menu fascism! 
        ;; (setq tail menulist)
        ;; (dolist (item tail)
        ;;   (when (imenu--subalist-p item)
        ;;     (push item keep-at-top)
        ;;     (setq menulist (delq item menulist))))
        (if imenu-sort-function
            (setq menulist (sort menulist imenu-sort-function)))
        (if (> (length menulist) imenu-max-items)
            (setq menulist
                  (mapcar
                   (lambda (menu)
                     (cons (format "From: %s" (caar menu)) menu))
                   (imenu--split menulist imenu-max-items))))
        (cons title
              (nconc (nreverse keep-at-top) menulist))))

In GNU Emacs 23.2.1 (i386-mingw-nt6.1.7601)
 of 2010-05-08 on G41R2F1
Windowing system distributor `Microsoft Corp.', version 6.1.7601
configured using `configure --with-gcc (3.4) --no-opt --cflags -Ic:/xpm/include'
Important settings:
  value of $LC_ALL: nil
  value of $LC_COLLATE: nil
  value of $LC_CTYPE: nil
  value of $LC_MESSAGES: nil
  value of $LC_MONETARY: nil
  value of $LC_NUMERIC: nil
  value of $LC_TIME: nil
  value of $LANG: ENU
  value of $XMODIFIERS: nil
  locale-coding-system: cp1252
  default enable-multibyte-characters: t
Major mode: Emacs-Lisp
Minor modes in effect:
  auto-revert-mode: t
  yas/minor-mode: t
  global-hl-line-mode: t
  hl-line-mode: t
  global-auto-complete-mode: t
  auto-complete-mode: t
  tooltip-mode: t
  mouse-wheel-mode: t
  menu-bar-mode: t
  file-name-shadow-mode: t
  global-font-lock-mode: t
  font-lock-mode: t
  blink-cursor-mode: t
  auto-encryption-mode: t
  auto-compression-mode: t
  line-number-mode: t
  transient-mark-mode: t
Recent input:
Recent messages:
Load-path shadows:
/users/dino/elisp/linum hides c:/emacs/lisp/linum
/users/dino/elisp/css-mode hides c:/emacs/lisp/textmodes/css-mode
Features:
(browse-url mailalias mailclient sendmail gnus-msg gnus-art mm-uu
mml2015 pgg pgg-parse pgg-def epg-config mm-view smime dig gnus-sum nnoo
gnus-group gnus-undo nnmail mail-source format-spec gnus-start gnus-spec
gnus-int gnus-range gnus-win gnus gnus-ems shadow sort mail-extr message
ecomplete rfc822 mml mml-sec password-cache mm-decode mm-bodies
mm-encode mailcap mail-parse rfc2231 rfc2047 rfc2045 qp ietf-drums
mailabbrev nnheader gnus-util netrc time-date mm-util mail-prsvr
gmm-utils wid-edit mailheader canlock sha1 hex-util hashcash mail-utils
emacsbug help-mode view js find-func dired-aux
flymake-for-jslint-for-wsh flymake-cursor flymake autopair espresso
bytecomp byte-compile ido json thingatpt etags imenu newcomment cc-mode
cc-fonts cc-menus cc-cmds multi-isearch grep compile comint ring
time-stamp sgml-mode autorevert server cperl-mode paren mic-paren
hideshow easymenu cc-styles cc-align cc-engine cc-vars cc-defs dired
regexp-opt defaultcontent yasnippet-bundle dropdown-list yasnippet
easy-mmode cl cl-19 tfs skeleton httpget hl-line advice help-fns
advice-preload auto-complete-config auto-complete edmacro kmacro popup
tooltip ediff-hook vc-hooks lisp-float-type mwheel dos-w32 disp-table
ls-lisp w32-win w32-vars tool-bar dnd fontset image fringe lisp-mode
register page menu-bar rfn-eshadow timer select scroll-bar mldrag mouse
jit-lock font-lock syntax facemenu font-core frame cham georgian
utf-8-lang misc-lang vietnamese tibetan thai tai-viet lao korean
japanese hebrew greek romanian slovak czech european ethiopic indian
cyrillic chinese case-table epa-hook jka-cmpr-hook help simple abbrev
loaddefs button minibuffer faces cus-face files text-properties overlay
md5 base64 format env code-pages mule custom widget
hashtable-print-readable backquote make-network-process multi-tty emacs)