* lisp/menu-bar.el (menu-bar-showhide-menu): Add "Context Menus".
* lisp/mouse.el (context-menu-undo): Add "in Region" to the titles
when the region is active.
(context-menu-region): Use 'mouse-yank-from-menu' in menu items
created from 'yank-menu' for submenu "Paste from Kill Menu".
(context-menu-region): Add submenu "Select" with things to mark.
(mark-thing-at-mouse, mouse-yank-from-menu): New functions.
* lisp/thingatpt.el (bounds-of-thing-at-mouse): New function.
* lisp/progmodes/elisp-mode.el (elisp-context-menu):
* lisp/progmodes/prog-mode.el (prog-context-menu):
Use full symbol/identifier names in :help strings.
Suggested by Martin Rudalics <rudalics@gmx.at>
:visible (and (display-graphic-p) (fboundp 'x-show-tip))
:button (:toggle . tooltip-mode)))
+ (bindings--define-key menu [showhide-context-menu]
+ '(menu-item "Context Menus" context-menu-mode
+ :help "Turn mouse-3 context menus on/off"
+ :button (:toggle . context-menu-mode)))
+
(bindings--define-key menu [menu-bar-mode]
'(menu-item "Menu Bar" toggle-menu-bar-mode-from-frame
:help "Turn menu bar on/off"
(listp pending-undo-list)
(consp buffer-undo-list)))
(define-key-after menu [undo]
- '(menu-item "Undo" undo
+ `(menu-item ,(if (region-active-p) "Undo in Region" "Undo") undo
:help "Undo last edits")))
(when (and (not buffer-read-only)
(undo--last-change-was-undo-p buffer-undo-list))
(define-key-after menu [undo-redo]
- '(menu-item "Redo" undo-redo
+ `(menu-item (if undo-in-region "Redo in Region" "Redo") undo-redo
:help "Redo last undone edits")))
menu)
-(defun context-menu-region (menu _click)
+(defun context-menu-region (menu click)
"Populate MENU with region commands."
(define-key-after menu [separator-region] menu-bar-separator)
(when (and mark-active (not buffer-read-only))
`(menu-item "Paste" mouse-yank-at-click
:help "Paste (yank) text most recently cut/copied")))
(when (and (cdr yank-menu) (not buffer-read-only))
- (define-key-after menu (if (featurep 'ns) [select-paste]
- [paste-from-menu])
- ;; ns-win.el said: Change text to be more consistent with
- ;; surrounding menu items `paste', etc."
- `(menu-item ,(if (featurep 'ns) "Select and Paste" "Paste from Kill Menu")
- yank-menu
- :help "Choose a string from the kill ring and paste it")))
+ (let ((submenu (make-sparse-keymap (propertize "Paste from Kill Menu"))))
+ (dolist (item yank-menu)
+ (when (consp item)
+ (define-key-after submenu (vector (car item))
+ `(menu-item ,(cadr item)
+ ,(lambda () (interactive)
+ (mouse-yank-from-menu click (car item)))))))
+ (define-key-after menu (if (featurep 'ns) [select-paste] [paste-from-menu])
+ `(menu-item ,(if (featurep 'ns) "Select and Paste" "Paste from Kill Menu")
+ ,submenu
+ :help "Choose a string from the kill ring and paste it"))))
(when (and mark-active (not buffer-read-only))
(define-key-after menu [clear]
'(menu-item "Clear" delete-active-region
:help
"Delete text in region between mark and current position")))
- (define-key-after menu [mark-whole-buffer]
- '(menu-item "Select All" mark-whole-buffer
- :help "Mark the whole buffer for a subsequent cut/copy"))
+
+ (let ((submenu (make-sparse-keymap (propertize "Select"))))
+ (define-key-after submenu [mark-whole-buffer]
+ `(menu-item "All"
+ ,(lambda (e) (interactive "e") (mark-thing-at-mouse e 'buffer))
+ :help "Mark the whole buffer for a subsequent cut/copy"))
+ (define-key-after submenu [mark-line]
+ `(menu-item "Line"
+ ,(lambda (e) (interactive "e") (mark-thing-at-mouse e 'line))
+ :help "Mark the line at click for a subsequent cut/copy"))
+ (define-key-after submenu [mark-defun]
+ `(menu-item "Defun"
+ ,(lambda (e) (interactive "e") (mark-thing-at-mouse e 'defun))
+ :help "Mark the defun at click for a subsequent cut/copy"))
+ (define-key-after submenu [mark-list]
+ `(menu-item "List"
+ ,(lambda (e) (interactive "e") (mark-thing-at-mouse e 'list))
+ :help "Mark the list at click for a subsequent cut/copy"))
+ (define-key-after submenu [mark-symbol]
+ `(menu-item "Symbol"
+ ,(lambda (e) (interactive "e") (mark-thing-at-mouse e 'symbol))
+ :help "Mark the symbol at click for a subsequent cut/copy"))
+ (when (region-active-p)
+ (define-key-after submenu [mark-none]
+ `(menu-item "None"
+ ,(lambda (_e) (interactive "e") (deactivate-mark))
+ :help "Deactivate the region")))
+
+ (define-key-after menu [select-region]
+ `(menu-item "Select" ,submenu)))
menu)
(defun context-menu-ffap (menu click)
(global-set-key [S-f10] 'context-menu-open)
+(defun mark-thing-at-mouse (click thing)
+ "Activate the region around THING found near the mouse CLICK."
+ (let ((bounds (bounds-of-thing-at-mouse click thing)))
+ (when bounds
+ (goto-char (if mouse-select-region-move-to-beginning
+ (car bounds) (cdr bounds)))
+ (push-mark (if mouse-select-region-move-to-beginning
+ (cdr bounds) (car bounds))
+ t 'activate))))
+
+(defun mouse-yank-from-menu (click string)
+ "Insert STRING at mouse CLICK."
+ ;; Give temporary modes such as isearch a chance to turn off.
+ (run-hooks 'mouse-leave-buffer-hook)
+ (when select-active-regions
+ (deactivate-mark))
+ (or mouse-yank-at-point (mouse-set-point click))
+ (push-mark)
+ (insert string))
+
\f
;; Commands that operate on windows.
(when (thing-at-mouse click 'symbol)
(define-key-after menu [elisp-separator] menu-bar-separator
'middle-separator)
- (define-key-after menu [info-lookup-symbol]
- '(menu-item "Look up in Manual"
- (lambda (click) (interactive "e")
- (info-lookup-symbol
- (intern (thing-at-mouse click 'symbol t))))
- :help "Display definition in relevant manual")
- 'elisp-separator)
+
(let* ((string (thing-at-mouse click 'symbol t))
(symbol (when (stringp string) (intern string)))
(title (cond
((not (symbolp symbol)) nil)
((and (facep symbol) (not (fboundp symbol)))
"Face")
- ((and (fboundp symbol) (boundp symbol)
- (memq symbol minor-mode-list))
- "Mode")
((and (fboundp symbol)
(not (or (boundp symbol) (facep symbol))))
"Function")
((or (fboundp symbol) (boundp symbol) (facep symbol))
"Symbol"))))
(when title
+ (define-key-after menu [info-lookup-symbol]
+ `(menu-item "Look up in Manual"
+ (lambda (_click) (interactive "e")
+ (info-lookup-symbol ',symbol))
+ :help ,(format "Find `%s' in relevant manual" symbol))
+ 'elisp-separator)
(define-key-after menu [describe-symbol]
`(menu-item (format "Describe %s" ,title)
(lambda (_click) (interactive "e")
(describe-symbol ',symbol))
- :help "Display the full documentation of symbol")
+ :help ,(format "Display the documentation of `%s'" symbol))
'elisp-separator))))
menu)
(require 'xref)
(define-key-after menu [prog-separator] menu-bar-separator
'middle-separator)
- (when (not (xref-marker-stack-empty-p))
+
+ (unless (xref-marker-stack-empty-p)
(define-key-after menu [xref-pop]
'(menu-item "Back Definition" xref-pop-marker-stack
:help "Back to the position of the last search")
'prog-separator))
- (when (save-excursion
- (mouse-set-point click)
- (xref-backend-identifier-at-point
- (xref-find-backend)))
- (define-key-after menu [xref-find-ref]
- '(menu-item "Find References" xref-find-references-at-mouse
- :help "Find references to identifier")
- 'prog-separator))
- (when (save-excursion
- (mouse-set-point click)
- (xref-backend-identifier-at-point
- (xref-find-backend)))
- (define-key-after menu [xref-find-def]
- '(menu-item "Find Definition" xref-find-definitions-at-mouse
- :help "Find definition of identifier")
- 'prog-separator))
+
+ (let ((identifier (save-excursion
+ (mouse-set-point click)
+ (xref-backend-identifier-at-point
+ (xref-find-backend)))))
+ (when identifier
+ (define-key-after menu [xref-find-ref]
+ `(menu-item "Find References" xref-find-references-at-mouse
+ :help ,(format "Find references to `%s'" identifier))
+ 'prog-separator)
+ (define-key-after menu [xref-find-def]
+ `(menu-item "Find Definition" xref-find-definitions-at-mouse
+ :help ,(format "Find definition of `%s'" identifier))
+ 'prog-separator)))
menu)
(defvar prog-mode-map
(if (and (<= real-beg orig) (<= orig end) (< real-beg end))
(cons real-beg end))))))))))
-;;;###autoload
-(defun thing-at-mouse (event thing &optional no-properties)
- "Return the THING at mouse click.
-Like `thing-at-point', but tries to use the event
-where the mouse button is clicked to find a thing nearby."
- (save-excursion
- (mouse-set-point event)
- (thing-at-point thing no-properties)))
-
;;;###autoload
(defun thing-at-point (thing &optional no-properties)
"Return the THING at point.
(set-text-properties 0 (length text) nil text))
text)))
+;;;###autoload
+(defun bounds-of-thing-at-mouse (event thing)
+ "Determine the start and end locations for the THING at mouse click.
+Like `bounds-of-thing-at-point', but tries to use the EVENT
+where the mouse button is clicked to find the thing nearby."
+ (save-excursion
+ (mouse-set-point event)
+ (bounds-of-thing-at-point thing)))
+
+;;;###autoload
+(defun thing-at-mouse (event thing &optional no-properties)
+ "Return the THING at mouse click.
+Like `thing-at-point', but tries to use the EVENT
+where the mouse button is clicked to find the thing nearby."
+ (save-excursion
+ (mouse-set-point event)
+ (thing-at-point thing no-properties)))
+
;; Go to beginning/end
(defun beginning-of-thing (thing)