Mercurial > emacs
changeset 10371:629821e2b42e
Better format of files-by-directory menus.
Split big menus into sub-menus.
(msb-max-menu-items): Changed default value. This variable
now depicts the maximum number of items in a sub-menu.
(msb-display-most-recently-used): Changed default value.
(mouse-select-buffer): Now handles several levels of
sub-menus. New format on return value.
author | Richard M. Stallman <rms@gnu.org> |
---|---|
date | Mon, 09 Jan 1995 22:16:23 +0000 |
parents | 4b1c8dc724e6 |
children | bdf897e70017 |
files | lisp/msb.el |
diffstat | 1 files changed, 116 insertions(+), 77 deletions(-) [+] |
line wrap: on
line diff
--- a/lisp/msb.el Mon Jan 09 18:31:22 1995 +0000 +++ b/lisp/msb.el Mon Jan 09 22:16:23 1995 +0000 @@ -3,6 +3,7 @@ ;; ;; Author: Lars Lindberg <Lars.Lindberg@sypro.cap.se> ;; Created: 8 Oct 1993 +;; Lindberg's last update version: 3.27 ;; Keywords: mouse buffer menu ;; ;; This program is free software; you can redistribute it and/or modify @@ -51,7 +52,8 @@ ;; Also check out the variable `msb-display-invisible-buffers-p'. ;; Known bugs: -;; - `msb' does not work on a non-X-toolkit Emacs. +;; - Files-by-directory +;; + No possibility to show client/changed buffers separately ;; Future enhancements: ;; - [Mattes] had a suggestion about sorting files by extension. ;; I (Lars Lindberg) think this case could be solved if msb.el was @@ -211,10 +213,9 @@ (defvar msb-files-by-directory-sort-key 0 "*The sort key for files sorted by directory") -(defvar msb-max-menu-items 25 +(defvar msb-max-menu-items 15 "*The maximum number of items in a menu. -If this variable is set to 15 for instance, then the 15 latest used -buffer that fits in a certain submenu will appear in that submenu. +If this variable is set to 15 for instance, then the submenu will be split up in minor parts, 15 items each. Nil means no limit.") (defvar msb-max-file-menu-items 10 @@ -224,15 +225,17 @@ number of buffers that are clumped togehter from different directories. +Set this to 1 if you want one menu per directory instead of clumping +them together. + If the value is not a number, then the value 10 is used.") (defvar msb-most-recently-used-sort-key -1010 "*Where should the menu with the most recently used buffers be placed?") -(defvar msb-display-most-recently-used t +(defvar msb-display-most-recently-used 15 "*How many buffers should be in the most-recently-used menu. -No buffers at all if less than 1 or nil. -T means use the value of `msb-max-menu-items' in the way it is defined.") + No buffers at all if less than 1 or nil (or any non-number).") (defvar msb-most-recently-used-title "Most recently used (%d)" "*The title for the most-recently-used menu.") @@ -252,6 +255,9 @@ The default function to call for handling the appearance of a menu item. It should take to arguments, BUFFER and MAX-BUFFER-NAME-LENGTH, where the latter is the max length of all buffer names. + +The function should return the string to use in the menu. + When the function is called, BUFFER is the current buffer. This function is called for items in the variable `msb-menu-cond' that have nil as ITEM-HANDLING-FUNCTION. See `msb-menu-cond' for more @@ -331,7 +337,7 @@ (defvar msb--error nil) ;;; -;;; Some example function to be used for `msb-item-sort-function'. +;;; Some example function to be used for `msb-item-handling-function'. ;;; (defun msb-item-handler (buffer &optional maxbuf) "Create one string item, concerning BUFFER, for the buffer menu. @@ -386,7 +392,7 @@ (or buffer-file-name ""))) ;;; -;;; Some example function to be used for `msb-item-handling-function'. +;;; Some example function to be used for `msb-item-sort-function'. ;;; (defun msb-sort-by-name (item1 item2) "Sorts the items depending on their buffer-name @@ -417,10 +423,9 @@ (interactive "e") (let ((buffer (mouse-select-buffer event)) (window (posn-window (event-start event)))) - (cond - (buffer - (or (framep window) (select-window window)) - (switch-to-buffer (car (cdr buffer)))))) + (when buffer + (unless (framep window) (select-window window)) + (switch-to-buffer buffer))) nil) ;;; @@ -463,8 +468,6 @@ (lambda (item) (cond ((and path - msb-max-menu-items - (< (length buffers) msb-max-menu-items) (string= path (car item))) (push (cdr item) buffers) nil) @@ -507,10 +510,14 @@ (cond ((> (length buffers) max-clumped-together) (setq last-path (car first)) - (when top-found-p - (setq first (cons (concat (car first) "/...") - (cdr first))) - (setq top-found-p nil)) + (setq first + (cons (format (if top-found-p + "%s/... (%d)" + "%s (%d)") + (car first) + (length (cdr first))) + (cdr first))) + (setq top-found-p nil) (push first final-list) (setq first (car rest) rest (cdr rest)) @@ -531,22 +538,27 @@ (string= path (substring last-path 0 (length path)))))) - (when top-found-p - (setq first (cons (concat (car first) "/...") - (cdr first))) - (setq top-found-p nil)) + (setq first + (cons (format (if top-found-p + "%s/... (%d)" + "%s (%d)") + (car first) + (length (cdr first))) + (cdr first))) + (setq top-found-p nil) (push first final-list) (setq first (car rest) rest (cdr rest)) (setq path (car first) buffers (cdr first))))))) - (when top-found-p - (setq first (cons (concat (car first) - (if (string-match "/$" (car first)) - "..." - "/...")) - (cdr first))) - (setq top-found-p nil)) + (setq first + (cons (format (if top-found-p + "%s/... (%d)" + "%s (%d)") + (car first) + (length (cdr first))) + (cdr first))) + (setq top-found-p nil) (push first final-list) (nreverse final-list))) @@ -604,10 +616,7 @@ multi-flag)) (progn (when (eq result 'multi) (setq multi-flag t)) - t) - (or (not msb-max-menu-items) - (< (length (eval (aref fi 0))) - msb-max-menu-items))) + t)) collect fi until (and result (not (eq result 'multi))))) @@ -672,15 +681,9 @@ ;; Returns a list on the form ((TITLE . BUFFER-LIST)) for ;; the most recently used buffers. (defun msb--most-recently-used-menu (max-buffer-name-length) - (when (and msb-display-most-recently-used - (or (not (numberp msb-display-most-recently-used)) - (> msb-display-most-recently-used 0))) - (let* ((max-in-menu - (if (numberp msb-display-most-recently-used) - msb-display-most-recently-used - msb-max-menu-items)) - - (most-recently-used + (when (and (numberp msb-display-most-recently-used) + (> msb-display-most-recently-used 0)) + (let* ((most-recently-used (loop with n = 0 for buffer in (cdr (buffer-list)) if (save-excursion @@ -694,7 +697,7 @@ max-buffer-name-length) buffer)) and do (incf n) - until (and max-in-menu (>= n max-in-menu))))) + 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)) @@ -748,7 +751,11 @@ (sort (mapcar (function (lambda (buffer) - (cons (buffer-name buffer) + (cons (save-excursion + (set-buffer buffer) + (funcall msb-item-handling-function + buffer + max-buffer-name-length)) buffer))) (cdr buffer-list)) (function @@ -756,15 +763,14 @@ (string< (car item1) (car item2))))))))) (msb--choose-file-menu file-buffers)))) ;; Now make the menu - a list of (TITLE . BUFFER-LIST) - (let* ((buffers (buffer-list)) - menu + (let* (menu (most-recently-used (msb--most-recently-used-menu max-buffer-name-length)) (others (append file-buffers (loop for elt - across function-info-vector - for value = (msb--create-sort-item elt) - if value collect value)))) + 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. @@ -811,7 +817,7 @@ "Pop up several menus of buffers, for selection with the mouse. Returns the selected buffer or nil if no buffer is selected. -The way the buffers are splitted is conveniently handled with the +The way the buffers are split is conveniently handled with the variable `msb-menu-cond'." ;; Popup the menu and return the selected buffer. (when (or msb--error @@ -820,31 +826,33 @@ (frame-or-buffer-changed-p)) (setq msb--error nil) (setq msb--last-buffer-menu (msb--create-buffer-menu))) - (let ((position event)) + (let ((position event) + choice) (when (and (fboundp 'posn-x-y) (fboundp 'posn-window)) (let ((posX (car (posn-x-y (event-start event)))) (posY (cdr (posn-x-y (event-start event)))) - (posWind (posn-window (event-start event))) - name) + (posWind (posn-window (event-start event)))) ;; adjust position (setq posX (- posX (funcall msb-horizontal-shift-function)) position (list (list posX posY) posWind)))) - (setq name (x-popup-menu position msb--last-buffer-menu)) - ;; If toggle bring up the + (setq choice (x-popup-menu position msb--last-buffer-menu)) (cond - ((eq (car name) 'toggle) - (msb--toggle-menu-type) - (mouse-select-buffer event)) - ((and (numberp (car name)) - (null (cdr name))) - (let ((msb--last-buffer-menu (nthcdr 3 (assq (car name) msb--last-buffer-menu)))) + ((eq (car choice) 'toggle) + ;; Bring up the menu again with type toggled. + (msb--toggle-menu-type) + (mouse-select-buffer event)) + ((and (numberp (car choice)) + (null (cdr choice))) + (let ((msb--last-buffer-menu (nthcdr 3 (assq (car choice) msb--last-buffer-menu)))) (mouse-select-buffer event))) - ((and (stringp (car name)) - (null (cdr name))) - (cons nil name)) - (t - name)))) + ((while (numberp (car choice)) + (setq choice (cdr choice)))) + ((and (stringp (car choice)) + (null (cdr choice))) + (car choice)) + (t + (error "Unknown form for buffer: %s" choice))))) ;; Add separators (defun msb--add-separators (sorted-list) @@ -870,6 +878,37 @@ (list item))))) sorted-list))))) +(defun msb--split-menus-2 (list mcount result) + (cond + ((> (length list) msb-max-menu-items) + (let ((count 0) + sub-name + (tmp-list nil)) + (while (< count msb-max-menu-items) + (push (pop list) tmp-list) + (incf count)) + (setq tmp-list (nreverse tmp-list)) + (setq sub-name (concat (car (car tmp-list)) "...")) + (push (append (list mcount sub-name + 'keymap sub-name) + tmp-list) + result)) + (msb--split-menus-2 list (1+ mcount) result)) + ((null result) + list) + (t + (let (sub-name) + (setq sub-name (concat (car (car list)) "...")) + (push (append (list mcount sub-name + 'keymap sub-name) + list) + result)) + (nreverse result)))) + +(defun msb--split-menus (list) + (msb--split-menus-2 list 0 nil)) + + (defun msb--make-keymap-menu (raw-menu) (let ((end (cons '(nil) 'menu-bar-select-buffer)) (mcount 0)) @@ -880,15 +919,16 @@ ((eq 'separator sub-menu) (list 'separator "---")) (t - (append (list (incf mcount) (car sub-menu) - 'keymap (car sub-menu)) - (mapcar (function - (lambda (item) - (let ((string (car item)) - (buffer (cdr item))) - (cons (buffer-name buffer) - (cons string end))))) - (cdr sub-menu))))))) + (let ((buffers (mapcar (function + (lambda (item) + (let ((string (car item)) + (buffer (cdr item))) + (cons (buffer-name buffer) + (cons string end))))) + (cdr sub-menu)))) + (append (list (incf mcount) (car sub-menu) + 'keymap (car sub-menu)) + (msb--split-menus buffers))))))) raw-menu))) (defun menu-bar-update-buffers (&optional arg) @@ -951,4 +991,3 @@ (provide 'msb) (eval-after-load 'msb (run-hooks 'msb-after-load-hooks)) ;;; msb.el ends here -