From 87f9ec7afb1180d6dc1ef65134f59cddddda1d68 Mon Sep 17 00:00:00 2001 From: Sam Steingold Date: Thu, 18 Dec 2014 16:41:34 -0500 Subject: [PATCH] Keyboard interface (C-f10) to `mouse-buffer-menu' (C-down-mouse-1). * lisp/mouse.el (mouse-buffer-menu-map): Extract from `mouse-buffer-menu'. (mouse-buffer-menu): Use `mouse-buffer-menu-map'. * lisp/menu-bar.el (menu-bar-buffer-vector): Extract from `menu-bar-update-buffers'. (menu-bar-update-buffers): Use `menu-bar-buffer-vector'. (buffer-menu-open): New user command, bound globally to C-f10, provides a keyboard interface to `mouse-buffer-menu' (C-down-mouse-1). (mouse-buffer-menu-keymap): Use `menu-bar-buffer-vector' to convert the value returned by `mouse-buffer-menu-map' to a list acceptable to `popup-menu' for `buffer-menu-open'. --- etc/NEWS | 2 ++ lisp/ChangeLog | 14 ++++++++++++++ lisp/menu-bar.el | 44 +++++++++++++++++++++++++++++++++----------- lisp/mouse.el | 29 +++++++++++++++-------------- 4 files changed, 64 insertions(+), 25 deletions(-) diff --git a/etc/NEWS b/etc/NEWS index 3880fd14f0d..1358eafe275 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -183,6 +183,8 @@ for Unicode 8.0. This includes full support for directional isolates and the Bidirectional Parentheses Algorithm (BPA) specified by these Unicode standards. +** You can access `mouse-buffer-menu' (C-down-mouse-1) using C-f10. + * Changes in Specialized Modes and Packages in Emacs 25.1 ** ido diff --git a/lisp/ChangeLog b/lisp/ChangeLog index 9828b845368..b50d5844b58 100644 --- a/lisp/ChangeLog +++ b/lisp/ChangeLog @@ -1,3 +1,17 @@ +2014-12-18 Sam Steingold + + Keyboard interface (C-f10) to `mouse-buffer-menu' (C-down-mouse-1). + * mouse.el (mouse-buffer-menu-map): Extract from `mouse-buffer-menu'. + (mouse-buffer-menu): Use `mouse-buffer-menu-map'. + * menu-bar.el (menu-bar-buffer-vector): Extract from + `menu-bar-update-buffers'. + (menu-bar-update-buffers): Use `menu-bar-buffer-vector'. + (buffer-menu-open): New user command, bound globally to C-f10, + provides a keyboard interface to `mouse-buffer-menu' (C-down-mouse-1). + (mouse-buffer-menu-keymap): Use `menu-bar-buffer-vector' to + convert the value returned by `mouse-buffer-menu-map' to a list + acceptable to `popup-menu' for `buffer-menu-open'. + 2014-12-18 Artur Malabarba * let-alist.el (let-alist): Evaluate the `alist' argument only diff --git a/lisp/menu-bar.el b/lisp/menu-bar.el index 12fb192c355..8f33641a746 100644 --- a/lisp/menu-bar.el +++ b/lisp/menu-bar.el @@ -1938,6 +1938,19 @@ Buffers menu is regenerated." "Function to select the buffer chosen from the `Buffers' menu-bar menu. It must accept a buffer as its only required argument.") +(defun menu-bar-buffer-vector (alist) + ;; turn ((name . buffer) ...) into a menu + (let ((buffers-vec (make-vector (length alist) nil)) + (i (length alist))) + (dolist (pair alist) + (setq i (1- i)) + (aset buffers-vec i + (cons (car pair) + `(lambda () + (interactive) + (funcall menu-bar-select-buffer-function ,(cdr pair)))))) + buffers-vec)) + (defun menu-bar-update-buffers (&optional force) ;; If user discards the Buffers item, play along. (and (lookup-key (current-global-map) [menu-bar buffer]) @@ -1973,17 +1986,7 @@ It must accept a buffer as its only required argument.") name) )) alist)))) - ;; Now make the actual list of items. - (let ((buffers-vec (make-vector (length alist) nil)) - (i (length alist))) - (dolist (pair alist) - (setq i (1- i)) - (aset buffers-vec i - (cons (car pair) - `(lambda () - (interactive) - (funcall menu-bar-select-buffer-function ,(cdr pair)))))) - (list buffers-vec)))) + (list (menu-bar-buffer-vector alist)))) ;; Make a Frames menu if we have more than one frame. (when (cdr frames) @@ -2311,6 +2314,25 @@ If FRAME is nil or not given, use the selected frame." (global-set-key [f10] 'menu-bar-open) +(defun buffer-menu-open () + "Start key navigation of the buffer menu. +This is the keyboard interface to \\[mouse-buffer-menu]." + (interactive) + (popup-menu (mouse-buffer-menu-keymap) + (posn-at-x-y 0 0 nil t))) + +(global-set-key [C-f10] 'buffer-menu-open) + +(defun mouse-buffer-menu-keymap () + (let* ((menu (mouse-buffer-menu-map)) + (km (make-sparse-keymap (pop menu)))) + (dolist (item (nreverse menu)) + (let* ((name (pop item))) + (define-key km (vector (intern name)) + (list name 'keymap name + (menu-bar-buffer-vector item))))) + km)) + (defvar tty-menu-navigation-map (let ((map (make-sparse-keymap))) ;; The next line is disabled because it breaks interpretation of diff --git a/lisp/mouse.el b/lisp/mouse.el index 800db63aff6..6e86bc06c1a 100644 --- a/lisp/mouse.el +++ b/lisp/mouse.el @@ -1516,8 +1516,17 @@ This switches buffers in the window that you clicked on, and selects that window." (interactive "e") (mouse-minibuffer-check event) - (let ((buffers (buffer-list)) alist menu split-by-major-mode sum-of-squares) - ;; Make an alist of elements that look like (MENU-ITEM . BUFFER). + (let ((buf (x-popup-menu event (mouse-buffer-menu-map))) + (window (posn-window (event-start event)))) + (when buf + (select-window + (if (framep window) (frame-selected-window window) + window)) + (switch-to-buffer buf)))) + +(defun mouse-buffer-menu-map () + ;; Make an alist of elements that look like (MENU-ITEM . BUFFER). + (let ((buffers (buffer-list)) split-by-major-mode sum-of-squares) (dolist (buf buffers) ;; Divide all buffers into buckets for various major modes. ;; Each bucket looks like (MODE NAMESTRING BUFFERS...). @@ -1581,18 +1590,10 @@ and selects that window." (setq subdivided-menus (cons (cons "Others" others-list) subdivided-menus))))) - (setq menu (cons "Buffer Menu" (nreverse subdivided-menus)))) - (progn - (setq alist (mouse-buffer-menu-alist buffers)) - (setq menu (cons "Buffer Menu" - (mouse-buffer-menu-split "Select Buffer" alist))))) - (let ((buf (x-popup-menu event menu)) - (window (posn-window (event-start event)))) - (when buf - (select-window - (if (framep window) (frame-selected-window window) - window)) - (switch-to-buffer buf))))) + (cons "Buffer Menu" (nreverse subdivided-menus))) + (cons "Buffer Menu" + (mouse-buffer-menu-split "Select Buffer" + (mouse-buffer-menu-alist buffers)))))) (defun mouse-buffer-menu-alist (buffers) (let (tail -- 2.39.2