Many improvements for Context Menus (bug#9054)
* 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>
This commit is contained in:
parent
2386b08526
commit
ac6afe9c33
5 changed files with 111 additions and 50 deletions
|
@ -1315,6 +1315,11 @@ mail status in mode line"))
|
|||
: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"
|
||||
|
|
|
@ -418,16 +418,16 @@ Some context functions add menu items below the separator."
|
|||
(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))
|
||||
|
@ -455,21 +455,52 @@ Some context functions add menu items below the separator."
|
|||
`(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)
|
||||
|
@ -517,6 +548,26 @@ This is the keyboard interface to \\[context-menu-map]."
|
|||
|
||||
(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))
|
||||
|
||||
|
||||
;; Commands that operate on windows.
|
||||
|
||||
|
|
|
@ -158,22 +158,13 @@ All commands in `lisp-mode-shared-map' are inherited by this map.")
|
|||
(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")
|
||||
|
@ -183,11 +174,17 @@ All commands in `lisp-mode-shared-map' are inherited by this map.")
|
|||
((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)
|
||||
|
||||
|
|
|
@ -48,27 +48,26 @@
|
|||
(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
|
||||
|
|
|
@ -151,15 +151,6 @@ positions of the thing found."
|
|||
(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.
|
||||
|
@ -196,6 +187,24 @@ a symbol as a valid THING."
|
|||
(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)
|
||||
|
|
Loading…
Add table
Reference in a new issue