use xmalloc_unsafe in current_minor_maps
[bpt/emacs.git] / lisp / msb.el
index cc5a0ad..166c6c6 100644 (file)
@@ -1,20 +1,19 @@
 ;;; msb.el --- customizable buffer-selection with multiple menus
 
-;; Copyright (C) 1993, 1994, 1995, 1997, 1998, 1999, 2000, 2001, 2002,
-;;   2003, 2004, 2005, 2006, 2007 Free Software Foundation, Inc.
+;; Copyright (C) 1993-1995, 1997-2014 Free Software Foundation, Inc.
 
 ;; Author: Lars Lindberg <lars.lindberg@home.se>
-;; Maintainer: FSF
+;; Maintainer: emacs-devel@gnu.org
 ;; Created: 8 Oct 1993
 ;; Lindberg's last update version: 3.34
 ;; Keywords: mouse buffer menu
 
 ;; This file is part of GNU Emacs.
 
-;; GNU Emacs is free software; you can redistribute it and/or modify
+;; GNU Emacs is free software: you can redistribute it and/or modify
 ;; it under the terms of the GNU General Public License as published by
-;; the Free Software Foundation; either version 3, or (at your option)
-;; any later version.
+;; the Free Software Foundation, either version 3 of the License, or
+;; (at your option) any later version.
 
 ;; GNU Emacs is distributed in the hope that it will be useful,
 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
@@ -22,9 +21,7 @@
 ;; GNU General Public License for more details.
 
 ;; You should have received a copy of the GNU General Public License
-;; along with GNU Emacs; see the file COPYING.  If not, write to the
-;; Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
-;; Boston, MA 02110-1301, USA.
+;; along with GNU Emacs.  If not, see <http://www.gnu.org/licenses/>.
 
 ;;; Commentary:
 
 ;; hacked on by Dave Love.
 ;;; Code:
 
-(eval-when-compile (require 'cl))
+(eval-when-compile (require 'cl-lib))
 
-;;;
-;;; Some example constants to be used for `msb-menu-cond'.  See that
-;;; variable for more information.  Please note that if the condition
-;;; returns `multi', then the buffer can appear in several menus.
-;;;
+;;
+;; Some example constants to be used for `msb-menu-cond'.  See that
+;; variable for more information.  Please note that if the condition
+;; returns `multi', then the buffer can appear in several menus.
+;;
 (defconst msb--few-menus
   '(((and (boundp 'server-buffer-clients)
          server-buffer-clients
       (msb-menu-bar-update-buffers t)))
 
 (defcustom msb-menu-cond msb--very-many-menus
-  "*List of criteria for splitting the mouse buffer menu.
+  "List of criteria for splitting the mouse buffer menu.
 The elements in the list should be of this type:
  (CONDITION MENU-SORT-KEY MENU-TITLE ITEM-HANDLING-FN ITEM-SORT-FN).
 
@@ -266,7 +263,7 @@ error every time you do \\[msb]."
   :version "20.3")
 
 (defcustom msb-separator-diff 100
-  "*Non-nil means use separators.
+  "Non-nil means use separators.
 The separators will appear between all menus that have a sorting key
 that differs by this value or more."
   :type '(choice integer (const nil))
@@ -274,10 +271,10 @@ that differs by this value or more."
   :group 'msb)
 
 (defvar msb-files-by-directory-sort-key 0
-  "*The sort key for files sorted by directory.")
+  "The sort key for files sorted by directory.")
 
 (defcustom msb-max-menu-items 15
-  "*The maximum number of items in a menu.
+  "The maximum number of items in a menu.
 If this variable is set to 15 for instance, then the submenu will be
 split up in minor parts, 15 items each.  A value of nil means no limit."
   :type '(choice integer (const nil))
@@ -285,7 +282,7 @@ split up in minor parts, 15 items each.  A value of nil means no limit."
   :group 'msb)
 
 (defcustom msb-max-file-menu-items 10
-  "*The maximum number of items from different directories.
+  "The maximum number of items from different directories.
 
 When the menu is of type `file by directory', this is the maximum
 number of buffers that are clumped together from different
@@ -300,29 +297,29 @@ If the value is not a number, then the value 10 is used."
   :group 'msb)
 
 (defcustom msb-most-recently-used-sort-key -1010
-  "*Where should the menu with the most recently used buffers be placed?"
+  "Where should the menu with the most recently used buffers be placed?"
   :type 'integer
   :set 'msb-custom-set
   :group 'msb)
 
 (defcustom msb-display-most-recently-used 15
-  "*How many buffers should be in the most-recently-used menu.
+  "How many buffers should be in the most-recently-used menu.
 No buffers at all if less than 1 or nil (or any non-number)."
   :type 'integer
   :set 'msb-custom-set
   :group 'msb)
 
 (defcustom msb-most-recently-used-title "Most recently used (%d)"
-  "*The title for the most-recently-used menu."
+  "The title for the most-recently-used menu."
   :type 'string
   :set 'msb-custom-set
   :group 'msb)
 
-(defvar msb-horizontal-shift-function '(lambda () 0)
-  "*Function that specifies how many pixels to shift the top menu leftwards.")
+(defvar msb-horizontal-shift-function (lambda () 0)
+  "Function that specifies how many pixels to shift the top menu leftwards.")
 
 (defcustom msb-display-invisible-buffers-p nil
-  "*Show invisible buffers or not.
+  "Show invisible buffers or not.
 Non-nil means that the buffer menu should include buffers that have
 names that starts with a space character."
   :type 'boolean
@@ -330,7 +327,7 @@ names that starts with a space character."
   :group 'msb)
 
 (defvar msb-item-handling-function 'msb-item-handler
-  "*The appearance of a buffer menu.
+  "The appearance of a buffer menu.
 
 The default function to call for handling the appearance of a menu
 item.  It should take two arguments, BUFFER and MAX-BUFFER-NAME-LENGTH,
@@ -344,7 +341,7 @@ nil as ITEM-HANDLING-FUNCTION.  See `msb-menu-cond' for more
 information.")
 
 (defcustom msb-item-sort-function 'msb-sort-by-name
-  "*The order of items in a buffer menu.
+  "The order of items in a buffer menu.
 
 The default function to call for handling the order of items in a menu
 item.  This function is called like a sort function.  The items look
@@ -361,12 +358,15 @@ Set this to nil or t if you don't want any sorting (faster)."
   :group 'msb)
 
 (defcustom msb-files-by-directory nil
-  "*Non-nil means that files should be sorted by directory.
+  "Non-nil means that files should be sorted by directory.
 This is instead of the groups in `msb-menu-cond'."
   :type 'boolean
   :set 'msb-custom-set
   :group 'msb)
 
+(define-obsolete-variable-alias 'msb-after-load-hooks
+  'msb-after-load-hook "24.1")
+
 (defcustom msb-after-load-hook nil
   "Hook run after the msb package has been loaded."
   :type 'hook
@@ -386,7 +386,7 @@ This is instead of the groups in `msb-menu-cond'."
 ;;;
 ;;; Some example function to be used for `msb-item-handling-function'.
 ;;;
-(defun msb-item-handler (buffer &optional maxbuf)
+(defun msb-item-handler (_buffer &optional _maxbuf)
   "Create one string item, concerning BUFFER, for the buffer menu.
 The item looks like:
 *% <buffer-name>
@@ -399,8 +399,6 @@ Optional second argument MAXBUF is completely ignored."
     (format "%s%s %s" modified read-only name)))
 
 
-(eval-when-compile (require 'dired))
-
 ;; `dired' can be called with a list of the form (directory file1 file2 ...)
 ;; which causes `dired-directory' to be in the same form.
 (defun msb--dired-directory ()
@@ -412,7 +410,7 @@ Optional second argument MAXBUF is completely ignored."
         (error "Unknown type of `dired-directory' in buffer %s"
                (buffer-name)))))
 
-(defun msb-dired-item-handler (buffer &optional maxbuf)
+(defun msb-dired-item-handler (_buffer &optional _maxbuf)
   "Create one string item, concerning a dired BUFFER, for the buffer menu.
 The item looks like:
 *% <buffer-name>
@@ -704,18 +702,18 @@ See `msb-menu-cond' for a description of its elements."
        (multi-flag nil)
        function-info-list)
     (setq function-info-list
-         (loop for fi
-               across function-info-vector
-               if (and (setq result
-                             (eval (aref fi 1))) ;Test CONDITION
-                       (not (and (eq result 'no-multi)
-                                 multi-flag))
-                       (progn (when (eq result 'multi)
-                                (setq multi-flag t))
-                              t))
-               collect fi
-               until (and result
-                          (not (eq result 'multi)))))
+         (cl-loop for fi
+                   across function-info-vector
+                   if (and (setq result
+                                 (eval (aref fi 1))) ;Test CONDITION
+                           (not (and (eq result 'no-multi)
+                                     multi-flag))
+                           (progn (when (eq result 'multi)
+                                    (setq multi-flag t))
+                                  t))
+                   collect fi
+                   until (and result
+                              (not (eq result 'multi)))))
     (when (and (not function-info-list)
               (not result))
       (error "No catch-all in msb-menu-cond!"))
@@ -819,7 +817,7 @@ results in
 (defun msb--mode-menu-cond ()
   (let ((key msb-modes-key))
     (mapcar (lambda (item)
-             (incf key)
+             (cl-incf key)
              (list `( eq major-mode (quote ,(car item)))
                    key
                    (concat (cdr item) " (%d)")))
@@ -829,7 +827,8 @@ results in
                 (with-current-buffer buffer
                   (when (and (not (msb-invisible-buffer-p))
                              (not (assq major-mode mode-list)))
-                    (push (cons major-mode mode-name)
+                    (push (cons major-mode
+                                 (format-mode-line mode-name nil nil buffer))
                           mode-list))))
               mode-list)
             (lambda (item1 item2)
@@ -842,18 +841,18 @@ It takes the form ((TITLE . BUFFER-LIST)...)."
             (> msb-display-most-recently-used 0))
     (let* ((buffers (cdr (buffer-list)))
           (most-recently-used
-           (loop with n = 0
-                 for buffer in buffers
-                 if (with-current-buffer buffer
-                      (and (not (msb-invisible-buffer-p))
-                           (not (eq major-mode 'dired-mode))))
-                 collect (with-current-buffer buffer
-                           (cons (funcall msb-item-handling-function
-                                          buffer
-                                          max-buffer-name-length)
-                                 buffer))
-                 and do (incf n)
-                 until (>= n msb-display-most-recently-used))))
+           (cl-loop with n = 0
+                     for buffer in buffers
+                     if (with-current-buffer buffer
+                          (and (not (msb-invisible-buffer-p))
+                               (not (eq major-mode 'dired-mode))))
+                     collect (with-current-buffer buffer
+                               (cons (funcall msb-item-handling-function
+                                              buffer
+                                              max-buffer-name-length)
+                                     buffer))
+                     and do (cl-incf n)
+                     until (>= n msb-display-most-recently-used))))
       (cons (if (stringp msb-most-recently-used-title)
                (format msb-most-recently-used-title
                        (length most-recently-used))
@@ -900,29 +899,29 @@ It takes the form ((TITLE . BUFFER-LIST)...)."
     (when file-buffers
       (setq file-buffers
            (mapcar (lambda (buffer-list)
-                     (list* msb-files-by-directory-sort-key
-                             (car buffer-list)
-                             (sort
-                              (mapcar (lambda (buffer)
-                                        (cons (with-current-buffer buffer
-                                                (funcall
-                                                 msb-item-handling-function
-                                                 buffer
-                                                 max-buffer-name-length))
-                                              buffer))
-                                      (cdr buffer-list))
-                              (lambda (item1 item2)
-                                (string< (car item1) (car item2))))))
+                     `(,msb-files-by-directory-sort-key
+                        ,(car buffer-list)
+                        ,@(sort
+                           (mapcar (lambda (buffer)
+                                     (cons (with-current-buffer buffer
+                                             (funcall
+                                              msb-item-handling-function
+                                              buffer
+                                              max-buffer-name-length))
+                                           buffer))
+                                   (cdr buffer-list))
+                           (lambda (item1 item2)
+                             (string< (car item1) (car item2))))))
                     (msb--choose-file-menu file-buffers))))
     ;; Now make the menu - a list of (TITLE . BUFFER-LIST)
     (let* (menu
           (most-recently-used
            (msb--most-recently-used-menu max-buffer-name-length))
           (others (nconc file-buffers
-                          (loop for elt
-                                across function-info-vector
-                                for value = (msb--create-sort-item elt)
-                                if value collect value))))
+                          (cl-loop for elt
+                                   across function-info-vector
+                                   for value = (msb--create-sort-item elt)
+                                   if value collect value))))
       (setq menu
            (mapcar 'cdr                ;Remove the SORT-KEY
                    ;; Sort the menus - not the items.
@@ -1040,7 +1039,7 @@ variable `msb-menu-cond'."
          (tmp-list nil))
       (while (< count msb-max-menu-items)
        (push (pop list) tmp-list)
-       (incf count))
+       (cl-incf count))
       (setq tmp-list (nreverse tmp-list))
       (setq sub-name (concat (car (car tmp-list)) "..."))
       (push (nconc (list mcount sub-name
@@ -1077,7 +1076,7 @@ variable `msb-menu-cond'."
                                  (cons (buffer-name (cdr item))
                                        (cons (car item) end)))
                                (cdr sub-menu))))
-          (nconc (list (incf mcount) (car sub-menu)
+          (nconc (list (cl-incf mcount) (car sub-menu)
                        'keymap (car sub-menu))
                  (msb--split-menus buffers))))))
      raw-menu)))
@@ -1113,7 +1112,8 @@ variable `msb-menu-cond'."
                     (list (frame-parameter frame 'name)
                           (frame-parameter frame 'name)
                           (cons nil nil))
-                    'menu-bar-select-frame))
+                     `(lambda ()
+                        (interactive) (menu-bar-select-frame ,frame))))
                  frames)))))
       (setcdr global-buffers-menu-map
              (if (and buffers-menu frames-menu)
@@ -1133,7 +1133,10 @@ variable `msb-menu-cond'."
 ;;;###autoload
 (define-minor-mode msb-mode
   "Toggle Msb mode.
-With arg, turn Msb mode on if and only if arg is positive.
+With a prefix argument ARG, enable Msb mode if ARG is positive,
+and disable it otherwise.  If called from Lisp, enable the mode
+if ARG is omitted or nil.
+
 This mode overrides the binding(s) of `mouse-buffer-menu' to provide a
 different buffer menu using the function `msb'."
   :global t :group 'msb
@@ -1153,7 +1156,6 @@ different buffer menu using the function `msb'."
   nil)
 
 (provide 'msb)
-(eval-after-load "msb" '(run-hooks 'msb-after-load-hook 'msb-after-load-hooks))
+(run-hooks 'msb-after-load-hook)
 
-;; arch-tag: 403f9e82-b92e-4e7a-a797-5d6d9b76da36
 ;;; msb.el ends here