* lisp/mouse.el (context-menu-functions): Update default list.
(context-menu-overriding-function): Remove variable.
(context-menu-map): Reverse the order.
(context-menu-global, context-menu-local, context-menu-minor): New functions.
(context-menu-undo, context-menu-region): Add separators.
Use define-key-after instead of bindings--define-key.
(context-menu-entry): New variable.
(context-menu-mode): Use it.
* lisp/dired.el (dired-context-menu): New function.
(dired-mode): Add it to context-menu-functions.
* lisp/info.el (Info-context-menu): Reorder.
* lisp/net/goto-addr.el (goto-address-at-mouse):
Rename from goto-address-at-click.
(goto-address-context-menu): Use goto-address-at-mouse.
* lisp/progmodes/prog-mode.el (prog-context-menu): New function.
(prog-mode): Add it to context-menu-functions.
["Delete Image Tag..." image-dired-delete-tag
:help "Delete image tag from current or marked files"]))
+(defun dired-context-menu (menu)
+ (when (mouse-posn-property (event-start last-input-event) 'dired-filename)
+ (define-key menu [dired-separator-1] menu-bar-separator)
+ (let ((easy-menu (make-sparse-keymap "Immediate")))
+ (easy-menu-define nil easy-menu nil
+ '("Immediate"
+ ["Find This File" dired-mouse-find-file
+ :help "Edit file at mouse click"]
+ ["Find in Other Window" dired-mouse-find-file-other-window
+ :help "Edit file at mouse click in other window"]))
+ (dolist (item (reverse (lookup-key easy-menu [menu-bar immediate])))
+ (when (consp item)
+ (define-key menu (vector (car item)) (cdr item)))))
+ (define-key menu [dired-separator-2] menu-bar-separator))
+ menu)
+
\f
;;; Dired mode
(append dired-dnd-protocol-alist dnd-protocol-alist)))
(add-hook 'file-name-at-point-functions #'dired-file-name-at-point nil t)
(add-hook 'isearch-mode-hook #'dired-isearch-filenames-setup nil t)
+ (add-hook 'context-menu-functions 'dired-context-menu 5 t)
(run-mode-hooks 'dired-mode-hook))
\f
:help "Search for another occurrence of regular expression"]
"---"
("History"
- ["Back in history" Info-history-back :active Info-history
+ ["Back in History" Info-history-back :active Info-history
:help "Go back in history to the last node you were at"]
- ["Forward in history" Info-history-forward :active Info-history-forward
+ ["Forward in History" Info-history-forward :active Info-history-forward
:help "Go forward in history"]
["Show History" Info-history :active Info-history-list
:help "Go to menu of visited nodes"])
(defun Info-context-menu (menu)
(when (mouse-posn-property (event-start last-input-event) 'mouse-face)
- (bindings--define-key menu [Info-mouse-follow-nearest-node]
- '(menu-item "Follow link" Info-mouse-follow-nearest-node
- :help "Follow a link where you click")))
-
- (bindings--define-key menu [Info-history-back]
- '(menu-item "Back in history" Info-history-back :visible Info-history
- :help "Go back in history to the last node you were at"))
- (bindings--define-key menu [Info-history-forward]
- '(menu-item "Forward in history" Info-history-forward :visible Info-history-forward
- :help "Go forward in history"))
-
- (bindings--define-key menu [Info-up]
- '(menu-item "Up" Info-up :visible (Info-check-pointer "up")
- :help "Go up in the Info tree"))
- (bindings--define-key menu [Info-next]
- '(menu-item "Next" Info-next :visible (Info-check-pointer "next")
- :help "Go to the next node"))
- (bindings--define-key menu [Info-prev]
- '(menu-item "Previous" Info-prev :visible (Info-check-pointer "prev[ious]*")
- :help "Go to the previous node"))
- (bindings--define-key menu [Info-backward-node]
- '(menu-item "Backward" Info-backward-node
- :help "Go backward one node, considering all as a sequence"))
- (bindings--define-key menu [Info-forward-node]
- '(menu-item "Forward" Info-forward-node
- :help "Go forward one node, considering all as a sequence"))
-
- (define-key menu [Info-separator] menu-bar-separator)
+ (define-key menu [Info-separator-link-1] menu-bar-separator)
+ (define-key menu [Info-mouse-follow-nearest-node]
+ '(menu-item "Follow Link" Info-mouse-follow-nearest-node
+ :help "Follow a link where you click"))
+ (define-key menu [Info-separator-link-2] menu-bar-separator))
+
+ (define-key-after menu [Info-separator-1] menu-bar-separator)
+ (let ((easy-menu (make-sparse-keymap "Info")))
+ (easy-menu-define nil easy-menu nil
+ '("Info"
+ ["Back in History" Info-history-back :visible Info-history
+ :help "Go back in history to the last node you were at"]
+ ["Forward in History" Info-history-forward :visible Info-history-forward
+ :help "Go forward in history"]))
+ (dolist (item (lookup-key easy-menu [menu-bar info]))
+ (when (consp item)
+ (define-key-after menu (vector (car item)) (cdr item)))))
+ (define-key-after menu [Info-separator-2] menu-bar-separator)
+
menu)
(defvar info-tool-bar-map
(add-hook 'clone-buffer-hook 'Info-clone-buffer nil t)
(add-hook 'change-major-mode-hook 'font-lock-defontify nil t)
(add-hook 'isearch-mode-hook 'Info-isearch-start nil t)
- (add-hook 'context-menu-functions 'Info-context-menu nil t)
+ (add-hook 'context-menu-functions 'Info-context-menu 5 t)
(when Info-standalone
(add-hook 'quit-window-hook 'save-buffers-kill-emacs nil t))
(setq-local isearch-search-fun-function #'Info-isearch-search)
\f
;; Context menus.
-(defcustom context-menu-functions '(context-menu-undo context-menu-region)
+(defcustom context-menu-functions '(context-menu-undo
+ context-menu-region
+ context-menu-local
+ context-menu-minor)
"List of functions that produce the contents of the context menu."
:type 'hook
+ :options '(context-menu-undo
+ context-menu-region
+ context-menu-global
+ context-menu-local
+ context-menu-minor)
:version "28.1")
-(defvar context-menu-overriding-function nil
- "Function that can override the list produced by `context-menu-functions'.")
-
(defcustom context-menu-filter-function nil
"Function that can filter the list produced by `context-menu-functions'."
:type 'function
:version "28.1")
(defun context-menu-map ()
+ "Return composite menu map."
(let ((menu (make-sparse-keymap "Context Menu")))
- (if (functionp context-menu-overriding-function)
- (setq menu (funcall context-menu-overriding-function menu))
- (run-hook-wrapped 'context-menu-functions
- (lambda (fun)
- (setq menu (funcall fun menu))
- nil)))
- (setq menu (cons (car menu) (nreverse (cdr menu))))
+ (run-hook-wrapped 'context-menu-functions
+ (lambda (fun)
+ (setq menu (funcall fun menu))
+ nil))
(when (functionp context-menu-filter-function)
(setq menu (funcall context-menu-filter-function menu)))
menu))
+(defun context-menu-global (menu)
+ "Global submenus."
+ (run-hooks 'activate-menubar-hook 'menu-bar-update-hook)
+ (define-key-after menu [separator-global-1] menu-bar-separator)
+ (dolist (item (lookup-key global-map [menu-bar]))
+ (when (consp item)
+ (define-key-after menu (vector (car item))
+ (if (consp (cdr item))
+ (copy-sequence (cdr item))
+ (cdr item)))))
+ (define-key-after menu [separator-global-2] menu-bar-separator)
+ menu)
+
+(defun context-menu-local (menu)
+ "Major mode submenus."
+ (run-hooks 'activate-menubar-hook 'menu-bar-update-hook)
+ (define-key-after menu [separator-local-1] menu-bar-separator)
+ (dolist (item (local-key-binding [menu-bar]))
+ (when (consp item)
+ (define-key-after menu (vector (car item))
+ (if (consp (cdr item))
+ (copy-sequence (cdr item))
+ (cdr item)))))
+ (define-key-after menu [separator-local-2] menu-bar-separator)
+ menu)
+
+(defun context-menu-minor (menu)
+ "Minor mode submenus."
+ (run-hooks 'activate-menubar-hook 'menu-bar-update-hook)
+ (define-key-after menu [separator-minor-1] menu-bar-separator)
+ (dolist (item (minor-mode-key-binding [menu-bar]))
+ (when (and (consp item) (symbol-value (car item)))
+ (define-key-after menu (vector (cadr item))
+ (if (consp (cddr item))
+ (copy-sequence (cddr item))
+ (cddr item)))))
+ (define-key-after menu [separator-minor-2] menu-bar-separator)
+ menu)
+
(defun context-menu-undo (menu)
- (bindings--define-key menu [undo]
+ (define-key-after menu [separator-undo-1] menu-bar-separator)
+ (define-key-after menu [undo]
'(menu-item "Undo" undo
:visible (and (not buffer-read-only)
(not (eq t buffer-undo-list))
(listp pending-undo-list)
(consp buffer-undo-list)))
:help "Undo last edits"))
- (bindings--define-key menu [undo-redo]
+ (define-key-after menu [undo-redo]
'(menu-item "Redo" undo-redo
:visible (and (not buffer-read-only)
(undo--last-change-was-undo-p buffer-undo-list))
:help "Redo last undone edits"))
+ (define-key-after menu [separator-undo-2] menu-bar-separator)
menu)
(defun context-menu-region (menu)
- (bindings--define-key menu [cut]
+ (define-key-after menu [separator-region-1] menu-bar-separator)
+ (define-key-after menu [cut]
'(menu-item "Cut" kill-region
:visible (and mark-active (not buffer-read-only))
:help
"Cut (kill) text in region between mark and current position"))
- (bindings--define-key menu [copy]
+ (define-key-after menu [copy]
;; ns-win.el said: Substitute a Copy function that works better
;; under X (for GNUstep).
`(menu-item "Copy" ,(if (featurep 'ns)
:keys ,(if (featurep 'ns)
"\\[ns-copy-including-secondary]"
"\\[kill-ring-save]")))
- (bindings--define-key menu [paste]
+ (define-key-after menu [paste]
`(menu-item "Paste" mouse-yank-primary
:visible (funcall
',(lambda ()
kill-ring))
(not buffer-read-only))))
:help "Paste (yank) text most recently cut/copied"))
- (bindings--define-key menu (if (featurep 'ns) [select-paste]
- [paste-from-menu])
+ (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
:visible (and (cdr yank-menu) (not buffer-read-only))
:help "Choose a string from the kill ring and paste it"))
- (bindings--define-key menu [clear]
+ (define-key-after menu [clear]
'(menu-item "Clear" delete-active-region
:visible (and mark-active
(not buffer-read-only))
:help
"Delete the text in region between mark and current position"))
- (bindings--define-key menu [mark-whole-buffer]
+ (define-key-after menu [mark-whole-buffer]
'(menu-item "Select All" mark-whole-buffer
:help "Mark the whole buffer for a subsequent cut/copy"))
+ (define-key-after menu [separator-region-2] menu-bar-separator)
menu)
+(defvar context-menu-entry
+ `(menu-item ,(purecopy "Context Menu") ignore
+ :filter (lambda (_) (context-menu-map))))
+
(defvar context-menu--old-down-mouse-3 nil)
(defvar context-menu--old-mouse-3 nil)
(setq context-menu--old-mouse-3 (global-key-binding [mouse-3]))
(global-unset-key [mouse-3])
(setq context-menu--old-down-mouse-3 (global-key-binding [down-mouse-3]))
- (global-set-key [down-mouse-3]
- '(menu-item "Context Menu" ignore
- :filter (lambda (_) (context-menu-map)))))
+ (global-set-key [down-mouse-3] context-menu-entry))
(t
(if (not context-menu--old-down-mouse-3)
(global-unset-key [down-mouse-3])
(defun goto-address-context-menu (menu)
(when (mouse-posn-property (event-start last-input-event) 'goto-address)
- (bindings--define-key menu [goto-address-at-click]
- '(menu-item "Follow link" goto-address-at-click
- :help "Follow a link where you click"))
- (define-key menu [goto-address-separator] menu-bar-separator))
+ (define-key menu [goto-address-separator] menu-bar-separator)
+ (define-key menu [goto-address-at-mouse]
+ '(menu-item "Follow Link" goto-address-at-mouse
+ :help "Follow a link where you click")))
menu)
(defcustom goto-address-url-face 'link
(goto-char (match-beginning 0))))
(match-string-no-properties 0)))
-(defun goto-address-at-click (click)
- "Send to the e-mail address or load the URL at click."
+(defun goto-address-at-mouse (click)
+ "Send to the e-mail address or load the URL at mouse click."
(interactive "e")
(goto-address-at-point click))
(cond
(goto-address-mode
(jit-lock-register #'goto-address-fontify-region)
- (add-hook 'context-menu-functions 'goto-address-context-menu -10 t))
+ (add-hook 'context-menu-functions 'goto-address-context-menu 10 t))
(t
(jit-lock-unregister #'goto-address-fontify-region)
(save-restriction
display-line-numbers-mode
prettify-symbols-mode))
+(defun prog-context-menu (menu)
+ (when (featurep 'xref)
+ (define-key-after menu [prog-separator-1] menu-bar-separator)
+ (define-key-after menu [xref-find-def]
+ '(menu-item "Find Definition" xref-find-definitions-at-mouse
+ :visible (save-excursion
+ (mouse-set-point last-input-event)
+ (xref-backend-identifier-at-point (xref-find-backend)))
+ :help "Find definition of function or variable"))
+ (define-key-after menu [xref-pop]
+ '(menu-item "Back Definition" xref-pop-marker-stack
+ :visible (not (xref-marker-stack-empty-p))
+ :help "Back to the position of the last search"))
+ (define-key-after menu [prog-separator-2] menu-bar-separator))
+ menu)
+
(defvar prog-mode-map
(let ((map (make-sparse-keymap)))
(define-key map [?\C-\M-q] 'prog-indent-sexp)
"Major mode for editing programming language source code."
(setq-local require-final-newline mode-require-final-newline)
(setq-local parse-sexp-ignore-comments t)
+ (add-hook 'context-menu-functions 'prog-context-menu 10 t)
;; Any programming language is always written left to right.
(setq bidi-paragraph-direction 'left-to-right))