From 89fef1244ebd55041eb415ef7b9d59e3b1014adc Mon Sep 17 00:00:00 2001 From: Jim Porter Date: Tue, 7 Dec 2021 20:34:08 -0800 Subject: [PATCH] Add a 'top-separator' to the context menu This provides an anchor for context menu functions to use to insert their menu items after it. Using 'define-key' doesn't work properly in this case, since it inserts the items before the menu title, confusing the separator de-duplication in 'context-menu-map'. * lisp/mouse.el (context-menu-functions): Mention 'top-separator', 'middle-separator', and how to use them. (context-menu-map): Add 'top-separator' to the menu. * lisp/dired.el (dired-context-menu): * lisp/help-mode.el (help-mode-context-menu): * lisp/info.el (Info-context-menu): * lisp/net/eww.el (eww-context-menu): * lisp/net/goto-addr.el (goto-address-context-menu): Use 'top-separator'. --- lisp/dired.el | 5 +++-- lisp/help-mode.el | 10 ++++++---- lisp/info.el | 9 +++++---- lisp/mouse.el | 11 ++++++++++- lisp/net/eww.el | 14 ++++++++------ lisp/net/goto-addr.el | 8 +++++--- 6 files changed, 37 insertions(+), 20 deletions(-) diff --git a/lisp/dired.el b/lisp/dired.el index d0e547ba0b..b004d81495 100644 --- a/lisp/dired.el +++ b/lisp/dired.el @@ -2282,7 +2282,7 @@ dired-mode-operate-menu (defun dired-context-menu (menu click) "Populate MENU with Dired mode commands at CLICK." (when (mouse-posn-property (event-start click) 'dired-filename) - (define-key menu [dired-separator] menu-bar-separator) + (define-key-after menu [dired-separator] menu-bar-separator 'top-separator) (let ((easy-menu (make-sparse-keymap "Immediate"))) (easy-menu-define nil easy-menu nil '("Immediate" @@ -2292,7 +2292,8 @@ dired-context-menu :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-after menu (vector (car item)) (cdr item) + 'top-separator))))) menu) diff --git a/lisp/help-mode.el b/lisp/help-mode.el index 792f2e5af3..2ed20577f5 100644 --- a/lisp/help-mode.el +++ b/lisp/help-mode.el @@ -74,7 +74,8 @@ help-mode-menu (defun help-mode-context-menu (menu click) "Populate MENU with Help mode commands at CLICK." - (define-key menu [help-mode-separator] menu-bar-separator) + (define-key-after menu [help-mode-separator] menu-bar-separator + 'top-separator) (let ((easy-menu (make-sparse-keymap "Help-Mode"))) (easy-menu-define nil easy-menu nil '("Help-Mode" @@ -86,14 +87,15 @@ help-mode-context-menu :active help-xref-forward-stack])) (dolist (item (reverse (lookup-key easy-menu [menu-bar help-mode]))) (when (consp item) - (define-key menu (vector (car item)) (cdr item))))) + (define-key-after menu (vector (car item)) (cdr item) 'top-separator)))) (when (mouse-posn-property (event-start click) 'mouse-face) - (define-key menu [help-mode-push-button] + (define-key-after menu [help-mode-push-button] '(menu-item "Follow Link" (lambda (event) (interactive "e") (push-button event)) - :help "Follow the link at click"))) + :help "Follow the link at click") + 'top-separator)) menu) diff --git a/lisp/info.el b/lisp/info.el index 559460e8d2..05e9277698 100644 --- a/lisp/info.el +++ b/lisp/info.el @@ -4193,7 +4193,7 @@ Info-check-pointer (defun Info-context-menu (menu click) "Populate MENU with Info commands at CLICK." - (define-key menu [Info-separator] menu-bar-separator) + (define-key-after menu [Info-separator] menu-bar-separator 'top-separator) (let ((easy-menu (make-sparse-keymap "Info"))) (easy-menu-define nil easy-menu nil '("Info" @@ -4203,12 +4203,13 @@ Info-context-menu :help "Go forward in history"])) (dolist (item (reverse (lookup-key easy-menu [menu-bar info]))) (when (consp item) - (define-key menu (vector (car item)) (cdr item))))) + (define-key-after menu (vector (car item)) (cdr item) 'top-separator)))) (when (mouse-posn-property (event-start click) 'mouse-face) - (define-key menu [Info-mouse-follow-nearest-node] + (define-key-after menu [Info-mouse-follow-nearest-node] '(menu-item "Follow Link" Info-mouse-follow-nearest-node - :help "Follow a link where you click"))) + :help "Follow a link where you click") + 'top-separator)) menu) diff --git a/lisp/mouse.el b/lisp/mouse.el index af1eca12f4..744df5f918 100644 --- a/lisp/mouse.el +++ b/lisp/mouse.el @@ -286,7 +286,13 @@ context-menu-functions context-menu-minor) "List of functions that produce the contents of the context menu. Each function receives the menu and the mouse click event as its arguments -and should return the same menu with changes such as added new menu items." +and should return the same menu with changes such as added new menu items. + +Functions can insert new menu items in whatever order makes sense to them. +To help simplify the placement of new items, the menu provides the +separators `top-separator' and `middle-separator', which can be passed as +the last argument to `define-key-after' in order to position the new item +accordingly." :type '(repeat (choice (function-item context-menu-undo) (function-item context-menu-region) @@ -319,6 +325,9 @@ context-menu-map (click (or click last-input-event)) (fun (mouse-posn-property (event-start click) 'context-menu-function))) + ;; Add a separator to the top of the menu to provide an anchor for + ;; context menu functions to use. + (define-key-after menu [top-separator] menu-bar-separator) (if (functionp fun) (setq menu (funcall fun menu click)) diff --git a/lisp/net/eww.el b/lisp/net/eww.el index e86d21f889..7303e01a37 100644 --- a/lisp/net/eww.el +++ b/lisp/net/eww.el @@ -1106,7 +1106,7 @@ eww-mode-map (defun eww-context-menu (menu click) "Populate MENU with eww commands at CLICK." - (define-key menu [eww-separator] menu-bar-separator) + (define-key-after menu [eww-separator] menu-bar-separator 'top-separator) (let ((easy-menu (make-sparse-keymap "Eww"))) (easy-menu-define nil easy-menu nil '("Eww" @@ -1117,20 +1117,22 @@ eww-context-menu ["Reload" eww-reload t])) (dolist (item (reverse (lookup-key easy-menu [menu-bar eww]))) (when (consp item) - (define-key menu (vector (car item)) (cdr item))))) + (define-key-after menu (vector (car item)) (cdr item) 'top-separator)))) (when (or (mouse-posn-property (event-start click) 'shr-url) (mouse-posn-property (event-start click) 'image-url)) - (define-key menu [shr-mouse-browse-url-new-window] + (define-key-after menu [shr-mouse-browse-url-new-window] `(menu-item "Follow URL in new window" ,(if browse-url-new-window-flag 'shr-mouse-browse-url 'shr-mouse-browse-url-new-window) - :help "Browse the URL under the mouse cursor in a new window")) - (define-key menu [shr-mouse-browse-url] + :help "Browse the URL under the mouse cursor in a new window") + 'top-separator) + (define-key-after menu [shr-mouse-browse-url] `(menu-item "Follow URL" ,(if browse-url-new-window-flag 'shr-mouse-browse-url-new-window 'shr-mouse-browse-url) - :help "Browse the URL under the mouse cursor"))) + :help "Browse the URL under the mouse cursor") + 'top-separator)) menu) diff --git a/lisp/net/goto-addr.el b/lisp/net/goto-addr.el index 848bad3b0d..bb0f0b00ee 100644 --- a/lisp/net/goto-addr.el +++ b/lisp/net/goto-addr.el @@ -127,10 +127,12 @@ goto-address-highlight-keymap (defun goto-address-context-menu (menu click) "Populate MENU with `goto-address' commands at CLICK." (when (mouse-posn-property (event-start click) 'goto-address) - (define-key menu [goto-address-separator] menu-bar-separator) - (define-key menu [goto-address-at-mouse] + (define-key-after menu [goto-address-separator] menu-bar-separator + 'top-separator) + (define-key-after menu [goto-address-at-mouse] '(menu-item "Follow Link" goto-address-at-mouse - :help "Follow a link where you click"))) + :help "Follow a link where you click") + 'top-separator)) menu) (defcustom goto-address-url-face 'link -- 2.25.1