comparison lisp/msb.el @ 25050:1539c0070dd3

(msb-menu-bar-update-buffers): Renamed from menu-bar-update-buffers. (msb-custom-set, msb--toggle-menu-type): Call msb-menu-bar-update-buffers. (msb-mode): Revise the hook setting.
author Dave Love <fx@gnu.org>
date Fri, 23 Jul 1999 22:57:32 +0000
parents 19424321d8e1
children 514b71b0b8f8
comparison
equal deleted inserted replaced
25049:aa8c0196cf48 25050:1539c0070dd3
1 ;;; msb.el --- Customizable buffer-selection with multiple menus. 1 ;;; msb.el --- Customizable buffer-selection with multiple menus.
2 2
3 ;; Copyright (C) 1993, 94, 95, 97, 98, 99 Free Software Foundation, Inc. 3 ;; Copyright (C) 1993, 94, 95, 97, 98, 99 Free Software Foundation, Inc.
4 4
5 ;; Author: Lars Lindberg <Lars.G.Lindberg@capgemini.se> 5 ;; Author: Lars Lindberg <Lars.G.Lindberg@capgemini.se>
6 ;; Maintainer: FSF
6 ;; Created: 8 Oct 1993 7 ;; Created: 8 Oct 1993
7 ;; Lindberg's last update version: 3.34 8 ;; Lindberg's last update version: 3.34
8 ;; Keywords: mouse buffer menu 9 ;; Keywords: mouse buffer menu
9 10
10 ;; This file is part of GNU Emacs. 11 ;; This file is part of GNU Emacs.
221 :require 'msb) 222 :require 'msb)
222 223
223 (defun msb-custom-set (symbol value) 224 (defun msb-custom-set (symbol value)
224 "Set the value of custom variables for msb." 225 "Set the value of custom variables for msb."
225 (set symbol value) 226 (set symbol value)
226 (if (featurep 'msb) 227 (if (and (featurep 'msb) msb-mode)
227 ;; wait until package has been loaded before bothering to update 228 ;; wait until package has been loaded before bothering to update
228 ;; the buffer lists. 229 ;; the buffer lists.
229 (menu-bar-update-buffers t)) 230 (msb-menu-bar-update-buffers t)))
230 )
231 231
232 (defcustom msb-menu-cond msb--very-many-menus 232 (defcustom msb-menu-cond msb--very-many-menus
233 "*List of criteria for splitting the mouse buffer menu. 233 "*List of criteria for splitting the mouse buffer menu.
234 The elements in the list should be of this type: 234 The elements in the list should be of this type:
235 (CONDITION MENU-SORT-KEY MENU-TITLE ITEM-HANDLING-FN ITEM-SORT-FN). 235 (CONDITION MENU-SORT-KEY MENU-TITLE ITEM-HANDLING-FN ITEM-SORT-FN).
515 "Return t if optional BUFFER is an \"invisible\" buffer. 515 "Return t if optional BUFFER is an \"invisible\" buffer.
516 If the argument is left out or nil, then the current buffer is considered." 516 If the argument is left out or nil, then the current buffer is considered."
517 (and (> (length (buffer-name buffer)) 0) 517 (and (> (length (buffer-name buffer)) 0)
518 (eq ?\ (aref (buffer-name buffer) 0)))) 518 (eq ?\ (aref (buffer-name buffer) 0))))
519 519
520 ;; Strip one hierarchy level from the end of DIR.
521 (defun msb--strip-dir (dir) 520 (defun msb--strip-dir (dir)
521 "Strip one hierarchy level from the end of DIR."
522 (file-name-directory (directory-file-name dir))) 522 (file-name-directory (directory-file-name dir)))
523 523
524 ;; Create an alist with all buffers from LIST that lies under the same 524 ;; Create an alist with all buffers from LIST that lies under the same
525 ;; directory will be in the same item as the directory string. 525 ;; directory will be in the same item as the directory string.
526 ;; ((PATH1 . (BUFFER-1 BUFFER-2 ...)) (PATH2 . (BUFFER-K BUFFER-K+1...)) ...) 526 ;; ((PATH1 . (BUFFER-1 BUFFER-2 ...)) (PATH2 . (BUFFER-K BUFFER-K+1...)) ...)
561 (and result (list result)))))) 561 (and result (list result))))))
562 buffer-alist) 562 buffer-alist)
563 ;; Add the last result to the list 563 ;; Add the last result to the list
564 (list (cons path buffers)))))) 564 (list (cons path buffers))))))
565 565
566 ;; Format a suitable title for the menu item.
567 (defun msb--format-title (top-found-p path number-of-items) 566 (defun msb--format-title (top-found-p path number-of-items)
567 "Format a suitable title for the menu item."
568 (let ((new-path path)) 568 (let ((new-path path))
569 (when (and msb--home-dir 569 (when (and msb--home-dir
570 (string-match (concat "^" msb--home-dir) path)) 570 (string-match (concat "^" msb--home-dir) path))
571 (setq new-path (concat "~" 571 (setq new-path (concat "~"
572 (substring path (match-end 0))))) 572 (substring path (match-end 0)))))
575 575
576 ;; Variables for debugging. 576 ;; Variables for debugging.
577 (defvar msb--choose-file-menu-list) 577 (defvar msb--choose-file-menu-list)
578 (defvar msb--choose-file-menu-arg-list) 578 (defvar msb--choose-file-menu-arg-list)
579 579
580 ;; Choose file-menu with respect to directory for every buffer in LIST.
581 (defun msb--choose-file-menu (list) 580 (defun msb--choose-file-menu (list)
581 "Choose file-menu with respect to directory for every buffer in LIST."
582 (setq msb--choose-file-menu-arg-list list) 582 (setq msb--choose-file-menu-arg-list list)
583 (let ((buffer-alist (msb--init-file-alist list)) 583 (let ((buffer-alist (msb--init-file-alist list))
584 (final-list nil) 584 (final-list nil)
585 (max-clumped-together (if (numberp msb-max-file-menu-items) 585 (max-clumped-together (if (numberp msb-max-file-menu-items)
586 msb-max-file-menu-items 586 msb-max-file-menu-items
672 (cdr first)) 672 (cdr first))
673 final-list)) 673 final-list))
674 (setq top-found-p nil) 674 (setq top-found-p nil)
675 (nreverse final-list))) 675 (nreverse final-list)))
676 676
677 ;; Create a vector as:
678 ;; [BUFFER-LIST-VARIABLE CONDITION MENU-SORT-KEY MENU-TITLE ITEM-HANDLER SORTER)
679 ;; from an element in `msb-menu-cond'. See that variable for a
680 ;; description of its elements.
681 (defun msb--create-function-info (menu-cond-elt) 677 (defun msb--create-function-info (menu-cond-elt)
678 "Create a vector from an element MENU-COND-ELT of `msb-menu-cond'.
679 This takes the form:
680 \]BUFFER-LIST-VARIABLE CONDITION MENU-SORT-KEY MENU-TITLE ITEM-HANDLER SORTER)
681 See `msb-menu-cond' for a description of its elements."
682 (let* ((list-symbol (make-symbol "-msb-buffer-list")) 682 (let* ((list-symbol (make-symbol "-msb-buffer-list"))
683 (tmp-ih (and (> (length menu-cond-elt) 3) 683 (tmp-ih (and (> (length menu-cond-elt) 3)
684 (nth 3 menu-cond-elt))) 684 (nth 3 menu-cond-elt)))
685 (item-handler (if (and tmp-ih (fboundp tmp-ih)) 685 (item-handler (if (and tmp-ih (fboundp tmp-ih))
686 tmp-ih 686 tmp-ih
735 (when (and (not function-info-list) 735 (when (and (not function-info-list)
736 (not result)) 736 (not result))
737 (error "No catch-all in msb-menu-cond!")) 737 (error "No catch-all in msb-menu-cond!"))
738 function-info-list)) 738 function-info-list))
739 739
740 ;; Adds BUFFER to the menu depicted by FUNCTION-INFO
741 ;; All side-effects. Adds an element of form (BUFFER-TITLE . BUFFER)
742 ;; to the buffer-list variable in function-info.
743 (defun msb--add-to-menu (buffer function-info max-buffer-name-length) 740 (defun msb--add-to-menu (buffer function-info max-buffer-name-length)
741 "Add BUFFER to the menu depicted by FUNCTION-INFO.
742 All side-effects. Adds an element of form (BUFFER-TITLE . BUFFER)
743 to the buffer-list variable in function-info."
744 (let ((list-symbol (aref function-info 0))) ;BUFFER-LIST-VARIABLE 744 (let ((list-symbol (aref function-info 0))) ;BUFFER-LIST-VARIABLE
745 ;; Here comes the hairy side-effect! 745 ;; Here comes the hairy side-effect!
746 (set list-symbol 746 (set list-symbol
747 (cons (cons (funcall (aref function-info 4) ;ITEM-HANDLER 747 (cons (cons (funcall (aref function-info 4) ;ITEM-HANDLER
748 buffer 748 buffer
749 max-buffer-name-length) 749 max-buffer-name-length)
750 buffer) 750 buffer)
751 (eval list-symbol))))) 751 (eval list-symbol)))))
752 752
753 ;; Selects the appropriate menu for BUFFER.
754 ;; This is all side-effects, folks!
755 ;; This should be optimized.
756 (defsubst msb--choose-menu (buffer function-info-vector max-buffer-name-length) 753 (defsubst msb--choose-menu (buffer function-info-vector max-buffer-name-length)
754 "Select the appropriate menu for BUFFER."
755 ;; This is all side-effects, folks!
756 ;; This should be optimized.
757 (unless (and (not msb-display-invisible-buffers-p) 757 (unless (and (not msb-display-invisible-buffers-p)
758 (msb-invisible-buffer-p buffer)) 758 (msb-invisible-buffer-p buffer))
759 (condition-case nil 759 (condition-case nil
760 (save-excursion 760 (save-excursion
761 (set-buffer buffer) 761 (set-buffer buffer)
768 (format 768 (format
769 "In msb-menu-cond, error for buffer `%s'." 769 "In msb-menu-cond, error for buffer `%s'."
770 (buffer-name buffer))) 770 (buffer-name buffer)))
771 (error "%s" msb--error)))))) 771 (error "%s" msb--error))))))
772 772
773 ;; Return (SORT-KEY TITLE . BUFFER-LIST) or nil if the
774 ;; buffer-list is empty.
775 (defun msb--create-sort-item (function-info) 773 (defun msb--create-sort-item (function-info)
774 "Return (SORT-KEY TITLE . BUFFER-LIST) or nil if the buffer-list is empty."
776 (let ((buffer-list (eval (aref function-info 0)))) 775 (let ((buffer-list (eval (aref function-info 0))))
777 (when buffer-list 776 (when buffer-list
778 (let ((sorter (aref function-info 5)) ;SORTER 777 (let ((sorter (aref function-info 5)) ;SORTER
779 (sort-key (aref function-info 2))) ;MENU-SORT-KEY 778 (sort-key (aref function-info 2))) ;MENU-SORT-KEY
780 (when sort-key 779 (when sort-key
787 ((eq sorter t) 786 ((eq sorter t)
788 (nreverse buffer-list)) 787 (nreverse buffer-list))
789 (t 788 (t
790 (sort buffer-list sorter)))))))))) 789 (sort buffer-list sorter))))))))))
791 790
792 ;; Return ALIST as a sorted, aggregated alist, where all items with
793 ;; the same car element (according to SAME-PREDICATE) are aggregated
794 ;; together. The alist is first sorted by SORT-PREDICATE.
795 ;; Example:
796 ;; (msb--aggregate-alist
797 ;; '((a . a1) (a . a2) (b . b1) (c . c3) (a . a4) (a . a3) (b . b3) (b . b2))
798 ;; (function string=)
799 ;; (lambda (item1 item2)
800 ;; (string< (symbol-name item1) (symbol-name item2))))
801 ;; results in
802 ;; ((a a1 a2 a4 a3) (b b1 b3 b2) (c c3))
803 (defun msb--aggregate-alist (alist same-predicate sort-predicate) 791 (defun msb--aggregate-alist (alist same-predicate sort-predicate)
792 "Return ALIST as a sorted, aggregated alist.
793
794 In the result all items with the same car element (according to
795 SAME-PREDICATE) are aggregated together. The alist is first sorted by
796 SORT-PREDICATE.
797
798 Example:
799 (msb--aggregate-alist
800 '((a . a1) (a . a2) (b . b1) (c . c3) (a . a4) (a . a3) (b . b3) (b . b2))
801 (function string=)
802 (lambda (item1 item2)
803 (string< (symbol-name item1) (symbol-name item2))))
804 results in
805 ((a a1 a2 a4 a3) (b b1 b3 b2) (c c3))"
804 (when (not (null alist)) 806 (when (not (null alist))
805 (let (result 807 (let (result
806 same 808 same
807 tmp-old-car 809 tmp-old-car
808 tmp-same 810 tmp-same
849 (cdr (buffer-list))) 851 (cdr (buffer-list)))
850 mode-list) 852 mode-list)
851 (lambda (item1 item2) 853 (lambda (item1 item2)
852 (string< (cdr item1) (cdr item2))))))) 854 (string< (cdr item1) (cdr item2)))))))
853 855
854 ;; Returns a list on the form ((TITLE . BUFFER-LIST)) for
855 ;; the most recently used buffers.
856 (defun msb--most-recently-used-menu (max-buffer-name-length) 856 (defun msb--most-recently-used-menu (max-buffer-name-length)
857 "Return a list for the most recently used buffers.
858 It takes the form ((TITLE . BUFFER-LIST)...)."
857 (when (and (numberp msb-display-most-recently-used) 859 (when (and (numberp msb-display-most-recently-used)
858 (> msb-display-most-recently-used 0)) 860 (> msb-display-most-recently-used 0))
859 (let* ((buffers (cdr (buffer-list))) 861 (let* ((buffers (cdr (buffer-list)))
860 (most-recently-used 862 (most-recently-used
861 (loop with n = 0 863 (loop with n = 0
979 (defun msb--create-buffer-menu () 981 (defun msb--create-buffer-menu ()
980 (save-match-data 982 (save-match-data
981 (save-excursion 983 (save-excursion
982 (msb--create-buffer-menu-2)))) 984 (msb--create-buffer-menu-2))))
983 985
984 ;;;
985 ;;; Multi purpose function for selecting a buffer with the mouse.
986 ;;;
987 (defun msb--toggle-menu-type () 986 (defun msb--toggle-menu-type ()
987 "Multi purpose function for selecting a buffer with the mouse."
988 (interactive) 988 (interactive)
989 (setq msb-files-by-directory (not msb-files-by-directory)) 989 (setq msb-files-by-directory (not msb-files-by-directory))
990 ;; This gets a warning, but it is correct, 990 ;; This gets a warning, but it is correct,
991 ;; because this file redefines menu-bar-update-buffers. 991 ;; because this file redefines menu-bar-update-buffers.
992 (menu-bar-update-buffers t)) 992 (msb-menu-bar-update-buffers t))
993 993
994 (defun mouse-select-buffer (event) 994 (defun mouse-select-buffer (event)
995 "Pop up several menus of buffers, for selection with the mouse. 995 "Pop up several menus of buffers, for selection with the mouse.
996 Returns the selected buffer or nil if no buffer is selected. 996 Returns the selected buffer or nil if no buffer is selected.
997 997
1113 (nconc (list (incf mcount) (car sub-menu) 1113 (nconc (list (incf mcount) (car sub-menu)
1114 'keymap (car sub-menu)) 1114 'keymap (car sub-menu))
1115 (msb--split-menus buffers)))))) 1115 (msb--split-menus buffers))))))
1116 raw-menu))) 1116 raw-menu)))
1117 1117
1118 (defun menu-bar-update-buffers (&optional arg) 1118 (defun msb-menu-bar-update-buffers (&optional arg)
1119 "A re-written version of `menu-bar-update-buffers'."
1119 ;; If user discards the Buffers item, play along. 1120 ;; If user discards the Buffers item, play along.
1120 (when (and (lookup-key (current-global-map) [menu-bar buffer]) 1121 (when (and (lookup-key (current-global-map) [menu-bar buffer])
1121 (or (not (fboundp 'frame-or-buffer-changed-p)) 1122 (or (not (fboundp 'frame-or-buffer-changed-p))
1122 (frame-or-buffer-changed-p) 1123 (frame-or-buffer-changed-p)
1123 arg)) 1124 arg))
1174 (interactive "P") 1175 (interactive "P")
1175 (setq msb-mode (if arg 1176 (setq msb-mode (if arg
1176 (> (prefix-numeric-value arg) 0) 1177 (> (prefix-numeric-value arg) 0)
1177 (not msb-mode))) 1178 (not msb-mode)))
1178 (if msb-mode 1179 (if msb-mode
1179 (add-hook 'menu-bar-update-hook 'menu-bar-update-buffers) 1180 (progn
1180 (remove-hook 'menu-bar-update-hook 'menu-bar-update-buffers))) 1181 (add-hook 'menu-bar-update-hook 'msb-menu-bar-update-buffers)
1182 (remove-hook 'menu-bar-update-hook 'menu-bar-update-buffers))
1183 (remove-hook 'menu-bar-update-hook 'msb-menu-bar-update-buffers)
1184 (add-hook 'menu-bar-update-hook 'menu-bar-update-buffers))
1185 (run-hooks 'menu-bar-update-hook))
1181 1186
1182 (add-to-list 'minor-mode-map-alist (cons 'msb-mode msb-mode-map)) 1187 (add-to-list 'minor-mode-map-alist (cons 'msb-mode msb-mode-map))
1183 1188
1184 (provide 'msb) 1189 (provide 'msb)
1185 (eval-after-load 'msb (run-hooks 'msb-after-load-hooks)) 1190 (eval-after-load 'msb (run-hooks 'msb-after-load-hooks))