\f
;; Provide a mode-specific menu on a mouse button.
-(defun popup-menu (menu &optional position prefix)
- "Popup the given menu and call the selected option.
-MENU can be a keymap, an easymenu-style menu or a list of keymaps as for
-`x-popup-menu'.
-The menu is shown at the place where POSITION specifies. About
-the form of POSITION, see `popup-menu-normalize-position'.
-PREFIX is the prefix argument (if any) to pass to the command."
- (let* ((map (cond
- ((keymapp menu) menu)
- ((and (listp menu) (keymapp (car menu))) menu)
- (t (let* ((map (easy-menu-create-menu (car menu) (cdr menu)))
- (filter (when (symbolp map)
- (plist-get (get map 'menu-prop) :filter))))
- (if filter (funcall filter (symbol-function map)) map)))))
- event cmd
- (position (popup-menu-normalize-position position)))
- ;; The looping behavior was taken from lmenu's popup-menu-popup
- (while (and map (setq event
- ;; map could be a prefix key, in which case
- ;; we need to get its function cell
- ;; definition.
- (x-popup-menu position (indirect-function map))))
- ;; Strangely x-popup-menu returns a list.
- ;; mouse-major-mode-menu was using a weird:
- ;; (key-binding (apply 'vector (append '(menu-bar) menu-prefix events)))
- (setq cmd
- (if (and (not (keymapp map)) (listp map))
- ;; We were given a list of keymaps. Search them all
- ;; in sequence until a first binding is found.
- (let ((mouse-click (apply 'vector event))
- binding)
- (while (and map (null binding))
- (setq binding (lookup-key (car map) mouse-click))
- (if (numberp binding) ; `too long'
- (setq binding nil))
- (setq map (cdr map)))
- binding)
- ;; We were given a single keymap.
- (lookup-key map (apply 'vector event))))
- ;; Clear out echoing, which perhaps shows a prefix arg.
- (message "")
- ;; Maybe try again but with the submap.
- (setq map (if (keymapp cmd) cmd)))
- ;; If the user did not cancel by refusing to select,
- ;; and if the result is a command, run it.
- (when (and (null map) (commandp cmd))
- (setq prefix-arg prefix)
- ;; `setup-specified-language-environment', for instance,
- ;; expects this to be set from a menu keymap.
- (setq last-command-event (car (last event)))
- ;; mouse-major-mode-menu was using `command-execute' instead.
- (call-interactively cmd))))
-
-(defun popup-menu-normalize-position (position)
- "Convert the POSITION to the form which `popup-menu' expects internally.
-POSITION can an event, a posn- value, a value having
-form ((XOFFSET YOFFSET) WINDOW), or nil.
-If nil, the current mouse position is used."
- (pcase position
- ;; nil -> mouse cursor position
- (`nil
- (let ((mp (mouse-pixel-position)))
- (list (list (cadr mp) (cddr mp)) (car mp))))
- ;; Value returned from `event-end' or `posn-at-point'.
- ((pred posnp)
- (let ((xy (posn-x-y position)))
- (list (list (car xy) (cdr xy))
- (posn-window position))))
- ;; Event.
- ((pred eventp)
- (popup-menu-normalize-position (event-end position)))
- (t position)))
-
(defun minor-mode-menu-from-indicator (indicator)
"Show menu for minor mode specified by INDICATOR.
Interactively, INDICATOR is read using completion.
(deactivate-mark)))
(or mouse-yank-at-point (mouse-set-point click))
(let ((primary
- (cond
- ((eq (framep (selected-frame)) 'w32)
- ;; MS-Windows emulates PRIMARY in x-get-selection, but not
- ;; in x-get-selection-value (the latter only accesses the
- ;; clipboard). So try PRIMARY first, in case they selected
- ;; something with the mouse in the current Emacs session.
- (or (x-get-selection 'PRIMARY)
- (x-get-selection-value)))
- ((fboundp 'x-get-selection-value) ; MS-DOS and X.
- ;; On X, x-get-selection-value supports more formats and
- ;; encodings, so use it in preference to x-get-selection.
- (or (x-get-selection-value)
- (x-get-selection 'PRIMARY)))
- ;; FIXME: What about xterm-mouse-mode etc.?
- (t
- (x-get-selection 'PRIMARY)))))
+ (if (fboundp 'x-get-selection-value)
+ (if (eq (framep (selected-frame)) 'w32)
+ ;; MS-Windows emulates PRIMARY in x-get-selection, but not
+ ;; in x-get-selection-value (the latter only accesses the
+ ;; clipboard). So try PRIMARY first, in case they selected
+ ;; something with the mouse in the current Emacs session.
+ (or (x-get-selection 'PRIMARY)
+ (x-get-selection-value))
+ ;; Else MS-DOS or X.
+ ;; On X, x-get-selection-value supports more formats and
+ ;; encodings, so use it in preference to x-get-selection.
+ (or (x-get-selection-value)
+ (x-get-selection 'PRIMARY)))
+ ;; FIXME: What about xterm-mouse-mode etc.?
+ (x-get-selection 'PRIMARY))))
(unless primary
(error "No selection is available"))
(push-mark (point))