;;; menu-bar.el --- define a default menu bar
-;; Copyright (C) 1993-1995, 2000-2014 Free Software Foundation, Inc.
+;; Copyright (C) 1993-1995, 2000-2015 Free Software Foundation, Inc.
;; Author: Richard M. Stallman
;; Maintainer: emacs-devel@gnu.org
(bindings--define-key menu [set-tags-name]
'(menu-item "Set Tags File Name..." visit-tags-table
- :help "Tell Tags commands which tag table file to use"))
+ :visible (menu-bar-goto-uses-etags-p)
+ :help "Tell navigation commands which tag table file to use"))
(bindings--define-key menu [separator-tag-file]
- menu-bar-separator)
+ '(menu-item "--" nil :visible (menu-bar-goto-uses-etags-p)))
+
+ (bindings--define-key menu [xref-pop]
+ '(menu-item "Back" xref-pop-marker-stack
+ :visible (and (featurep 'xref)
+ (not (xref-marker-stack-empty-p)))
+ :help "Back to the position of the last search"))
- (bindings--define-key menu [apropos-tags]
- '(menu-item "Tags Apropos..." tags-apropos
+ (bindings--define-key menu [xref-apropos]
+ '(menu-item "Find Apropos..." xref-find-apropos
:help "Find function/variables whose names match regexp"))
- (bindings--define-key menu [next-tag-otherw]
- '(menu-item "Next Tag in Other Window"
- menu-bar-next-tag-other-window
- :enable (and (boundp 'tags-location-ring)
- (not (ring-empty-p tags-location-ring)))
- :help "Find next function/variable matching last tag name in another window"))
-
- (bindings--define-key menu [next-tag]
- '(menu-item "Find Next Tag"
- menu-bar-next-tag
- :enable (and (boundp 'tags-location-ring)
- (not (ring-empty-p tags-location-ring)))
- :help "Find next function/variable matching last tag name"))
- (bindings--define-key menu [find-tag-otherw]
- '(menu-item "Find Tag in Other Window..." find-tag-other-window
+
+ (bindings--define-key menu [xref-find-otherw]
+ '(menu-item "Find Definition in Other Window..."
+ xref-find-definitions-other-window
:help "Find function/variable definition in another window"))
- (bindings--define-key menu [find-tag]
- '(menu-item "Find Tag..." find-tag
+ (bindings--define-key menu [xref-find-def]
+ '(menu-item "Find Definition..." xref-find-definitions
:help "Find definition of function or variable"))
- (bindings--define-key menu [separator-tags]
+ (bindings--define-key menu [separator-xref]
menu-bar-separator)
(bindings--define-key menu [end-of-buf]
:help "Read a line number and go to that line"))
menu))
+(defun menu-bar-goto-uses-etags-p ()
+ (or (not (boundp 'xref-find-function))
+ (eq xref-find-function 'etags-xref-find)))
(defvar yank-menu (cons (purecopy "Select Yank") nil))
(fset 'yank-menu (cons 'keymap yank-menu))
:enable (and (cdr yank-menu) (not buffer-read-only))
:help "Choose a string from the kill ring and paste it"))
(bindings--define-key menu [paste]
- '(menu-item "Paste" yank
- :enable (and (or
- (gui-call gui-selection-exists-p 'CLIPBOARD)
- (if (featurep 'ns) ; like paste-from-menu
- (cdr yank-menu)
- kill-ring))
- (not buffer-read-only))
+ `(menu-item "Paste" yank
+ :enable (funcall
+ ',(lambda ()
+ (and (or
+ (gui-backend-selection-exists-p 'CLIPBOARD)
+ (if (featurep 'ns) ; like paste-from-menu
+ (cdr yank-menu)
+ kill-ring))
+ (not buffer-read-only))))
:help "Paste (yank) text most recently cut/copied"))
(bindings--define-key menu [copy]
;; ns-win.el said: Substitute a Copy function that works better
menu))
-(defun menu-bar-next-tag-other-window ()
- "Find the next definition of the tag already specified."
- (interactive)
- (find-tag-other-window nil t))
-
-(defun menu-bar-next-tag ()
- "Find the next definition of the tag already specified."
- (interactive)
- (find-tag nil t))
-
(define-obsolete-function-alias
'menu-bar-kill-ring-save 'kill-ring-save "24.1")
'(and mark-active (not buffer-read-only)))
(put 'clipboard-kill-ring-save 'menu-enable 'mark-active)
(put 'clipboard-yank 'menu-enable
- '(and (or (gui-call gui-selection-exists-p 'PRIMARY)
- (gui-call gui-selection-exists-p 'CLIPBOARD))
- (not buffer-read-only)))
+ `(funcall ',(lambda ()
+ (and (or (gui-backend-selection-exists-p 'PRIMARY)
+ (gui-backend-selection-exists-p 'CLIPBOARD))
+ (not buffer-read-only)))))
+
+(defvar gui-select-enable-clipboard)
(defun clipboard-yank ()
"Insert the clipboard contents, or the last stretch of killed text."
(frame-visible-p menu-frame))))
(defun menu-bar-non-minibuffer-window-p ()
- "Return non-nil if selected window of the menu frame is not a minibuf window.
-
-See the documentation of `menu-bar-menu-frame-live-and-visible-p'
-for the definition of the menu frame."
+ "Return non-nil if the menu frame's selected window is no minibuffer window.
+Return nil if the menu frame is dead or its selected window is a
+minibuffer window. The menu frame is the frame for which we are
+updating the menu."
(let ((menu-frame (or menu-updating-frame (selected-frame))))
- (not (window-minibuffer-p (frame-selected-window menu-frame)))))
+ (and (frame-live-p menu-frame)
+ (not (window-minibuffer-p
+ (frame-selected-window menu-frame))))))
(defun kill-this-buffer () ; for the menu bar
"Kill the current buffer.
"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])
(let ((buffers (buffer-list))
(frames (frame-list))
buffers-menu)
- ;; If requested, list only the N most recently selected buffers.
- (if (and (integerp buffers-menu-max-size)
- (> buffers-menu-max-size 1))
- (if (> (length buffers) buffers-menu-max-size)
- (setcdr (nthcdr buffers-menu-max-size buffers) nil)))
;; Make the menu of buffers proper.
(setq buffers-menu
- (let (alist)
+ (let ((i 0)
+ (limit (if (and (integerp buffers-menu-max-size)
+ (> buffers-menu-max-size 1))
+ buffers-menu-max-size most-positive-fixnum))
+ alist)
;; Put into each element of buffer-list
;; the name for actual display,
;; perhaps truncated in the middle.
- (dolist (buf buffers)
- (let ((name (buffer-name buf)))
+ (while buffers
+ (let* ((buf (pop buffers))
+ (name (buffer-name buf)))
(unless (eq ?\s (aref name 0))
(push (menu-bar-update-buffers-1
(cons buf
name (- (/ buffers-menu-buffer-name-length 2))))
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))))
+ alist)
+ ;; If requested, list only the N most recently
+ ;; selected buffers.
+ (when (= limit (setq i (1+ i)))
+ (setq buffers nil)))))
+ (list (menu-bar-buffer-vector alist))))
;; Make a Frames menu if we have more than one frame.
(when (cdr frames)
(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