emacs-elpa-diffs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[nongnu] elpa/git-commit 95b432530a 16/18: Do not set point when invokin


From: ELPA Syncer
Subject: [nongnu] elpa/git-commit 95b432530a 16/18: Do not set point when invoking context-menu
Date: Fri, 25 Mar 2022 13:58:20 -0400 (EDT)

branch: elpa/git-commit
commit 95b432530a6b131e63bec7411ee768f1dee9f629
Author: Jonas Bernoulli <jonas@bernoul.li>
Commit: Jonas Bernoulli <jonas@bernoul.li>

    Do not set point when invoking context-menu
---
 docs/magit-section.org  | 33 ++++++++++++++++-
 docs/magit-section.texi | 33 ++++++++++++++++-
 lisp/magit-diff.el      |  8 ++--
 lisp/magit-git.el       | 10 ++---
 lisp/magit-mode.el      | 11 +++---
 lisp/magit-section.el   | 98 +++++++++++++++++++++++++++++++++++++++++++++----
 6 files changed, 167 insertions(+), 26 deletions(-)

diff --git a/docs/magit-section.org b/docs/magit-section.org
index ce8d47b134..20397c3883 100644
--- a/docs/magit-section.org
+++ b/docs/magit-section.org
@@ -149,11 +149,15 @@ source for suitable examples before asking me for help.  
Thanks!
 
 - Function: magit-current-section ::
 
-  Return the section at point.
+  Return the section at point or where the context menu was invoked.
+  When using the context menu, return the section that the user
+  clicked on, provided the current buffer is the buffer in which
+  the click occured.  Otherwise return the section at point.
 
 - Function magit-section-at &optional position ::
 
-  Return the section at POSITION, defaulting to point.
+  Return the section at POSITION, defaulting to point.  Default to
+  point even when the context menu is used.
 
 - Function: magit-section-ident section ::
 
@@ -188,6 +192,31 @@ source for suitable examples before asking me for help.  
Thanks!
 
   Return non-nil if SECTION has content or an unused washer function.
 
+The next two functions are replacements for the Emacs functions that
+have the same name except for the ~magit-~ prefix.  Like
+~magit-current-section~ they do not act on point, the cursors position,
+but on the position where the user clicked to invoke the context menu.
+
+If your package provides a context menu and some of its commands act
+on the "thing at point", even if just as a default, then use the
+prefixed functions to teach them to instead use the click location
+when appropriate.
+
+- Function magit-point ::
+
+  Return point or the position where the context menu was invoked.
+  When using the context menu, return the position the user clicked
+  on, provided the current buffer is the buffer in which the click
+  occured.  Otherwise return the same value as ~point~.
+
+- Function magit-thing-at-point thing &optional no-properties ::
+
+  Return the THING at point or where the context menu was invoked.
+  When using the context menu, return the thing the user clicked
+  on, provided the current buffer is the buffer in which the click
+  occured.  Otherwise return the same value as ~thing-at-point~.
+  For the meaning of THING and NO-PROPERTIES see that function.
+
 * Matching Functions
 
 - Function: magit-section-match condition &optional (section 
(magit-current-section)) ::
diff --git a/docs/magit-section.texi b/docs/magit-section.texi
index 9fb8a09546..41fe361d97 100644
--- a/docs/magit-section.texi
+++ b/docs/magit-section.texi
@@ -193,12 +193,16 @@ buffer is reached.  FUNCTION has to move point forward or 
return
 @chapter Core Functions
 
 @defun magit-current-section
-Return the section at point.
+Return the section at point or where the context menu was invoked.
+When using the context menu, return the section that the user
+clicked on, provided the current buffer is the buffer in which
+the click occured.  Otherwise return the section at point.
 @end defun
 
 @table @asis
 @item Function magit-section-at &optional position
-Return the section at POSITION, defaulting to point.
+Return the section at POSITION, defaulting to point.  Default to
+point even when the context menu is used.
 @end table
 
 @defun magit-section-ident section
@@ -234,6 +238,31 @@ The return value has the form @code{(TYPE...)}.
 Return non-nil if SECTION has content or an unused washer function.
 @end defun
 
+The next two functions are replacements for the Emacs functions that
+have the same name except for the @code{magit-} prefix.  Like
+@code{magit-current-section} they do not act on point, the cursors position,
+but on the position where the user clicked to invoke the context menu.
+
+If your package provides a context menu and some of its commands act
+on the "thing at point", even if just as a default, then use the
+prefixed functions to teach them to instead use the click location
+when appropriate.
+
+@table @asis
+@item Function magit-point
+Return point or the position where the context menu was invoked.
+When using the context menu, return the position the user clicked
+on, provided the current buffer is the buffer in which the click
+occured.  Otherwise return the same value as @code{point}.
+
+@item Function magit-thing-at-point thing &optional no-properties
+Return the THING at point or where the context menu was invoked.
+When using the context menu, return the thing the user clicked
+on, provided the current buffer is the buffer in which the click
+occured.  Otherwise return the same value as @code{thing-at-point}.
+For the meaning of THING and NO-PROPERTIES see that function.
+@end table
+
 @node Matching Functions
 @chapter Matching Functions
 
diff --git a/lisp/magit-diff.el b/lisp/magit-diff.el
index d3d1593ac7..793a760527 100644
--- a/lisp/magit-diff.el
+++ b/lisp/magit-diff.el
@@ -1296,7 +1296,7 @@ for a revision."
   (interactive
    (pcase-let* ((mcommit (magit-section-value-if 'module-commit))
                 (atpoint (or mcommit
-                             (thing-at-point 'git-revision t)
+                             (magit-thing-at-point 'git-revision t)
                              (magit-branch-or-commit-at-point)))
                 (`(,args ,files) (magit-show-commit--arguments)))
      (list (or (and (not current-prefix-arg) atpoint)
@@ -1677,7 +1677,7 @@ the Magit-Status buffer for DIRECTORY."
   (and magit-diff-visit-previous-blob
        (not in-worktree)
        (not (oref section combined))
-       (not (< (point) (oref section content)))
+       (not (< (magit-point) (oref section content)))
        (= (char-after (line-beginning-position)) ?-)))
 
 (defvar magit-diff-visit-jump-to-change t)
@@ -1703,7 +1703,7 @@ the Magit-Status buffer for DIRECTORY."
            offset)))))
 
 (defun magit-diff-hunk-column (section goto-from)
-  (if (or (< (point)
+  (if (or (< (magit-point)
              (oref section content))
           (and (not goto-from)
                (= (char-after (line-beginning-position)) ?-)))
@@ -3346,7 +3346,7 @@ last (visual) lines of the region."
   "Return non-nil if point is inside the body of a hunk."
   (and (magit-section-match 'hunk)
        (when-let ((content (oref (magit-current-section) content)))
-         (> (point) content))))
+         (> (magit-point) content))))
 
 ;;; Diff Extract
 
diff --git a/lisp/magit-git.el b/lisp/magit-git.el
index 80b88725b2..f300f29267 100644
--- a/lisp/magit-git.el
+++ b/lisp/magit-git.el
@@ -1457,13 +1457,13 @@ to, or to some other symbolic-ref that points to the 
same ref."
 
 (defun magit--painted-branch-at-point (&optional type)
   (or (and (not (eq type 'remote))
-           (memq (get-text-property (point) 'font-lock-face)
+           (memq (get-text-property (magit-point) 'font-lock-face)
                  (list 'magit-branch-local
                        'magit-branch-current))
-           (when-let ((branch (thing-at-point 'git-revision t)))
+           (when-let ((branch (magit-thing-at-point 'git-revision t)))
              (cdr (magit-split-branch-name branch))))
       (and (not (eq type 'local))
-           (memq (get-text-property (point) 'font-lock-face)
+           (memq (get-text-property (magit-point) 'font-lock-face)
                  (list 'magit-branch-remote
                        'magit-branch-remote-head))
            (thing-at-point 'git-revision t))))
@@ -1486,7 +1486,7 @@ to, or to some other symbolic-ref that points to the same 
ref."
 
 (defun magit-commit-at-point ()
   (or (magit-section-value-if 'commit)
-      (thing-at-point 'git-revision t)
+      (magit-thing-at-point 'git-revision t)
       (when-let ((chunk (magit-current-blame-chunk 'addition t)))
         (oref chunk orig-rev))
       (and (derived-mode-p 'magit-stash-mode
@@ -1506,7 +1506,7 @@ to, or to some other symbolic-ref that points to the same 
ref."
                            (forge--pullreq-branch (oref it value))))
                      (magit-ref-p (format "refs/pullreqs/%s"
                                           (oref (oref it value) number))))))
-      (thing-at-point 'git-revision t)
+      (magit-thing-at-point 'git-revision t)
       (when-let ((chunk (magit-current-blame-chunk 'addition t)))
         (oref chunk orig-rev))
       (and magit-buffer-file-name
diff --git a/lisp/magit-mode.el b/lisp/magit-mode.el
index 54c054ec16..5bb9ed4139 100644
--- a/lisp/magit-mode.el
+++ b/lisp/magit-mode.el
@@ -1098,7 +1098,7 @@ Run hooks `magit-pre-refresh-hook' and 
`magit-post-refresh-hook'."
                        (lambda (window)
                          (with-selected-window window
                            (with-current-buffer buffer
-                             (when-let ((section (magit-current-section)))
+                             (when-let ((section (magit-section-at)))
                                `(( ,window
                                    ,section
                                    
,@(magit-refresh-get-relative-position)))))))
@@ -1135,16 +1135,17 @@ Run hooks `magit-pre-refresh-hook' and 
`magit-post-refresh-hook'."
 
 (defun magit-refresh-get-relative-position ()
   (when-let ((section (magit-current-section)))
-    (let ((start (oref section start)))
-      (list (- (line-number-at-pos (point))
+    (let ((start (oref section start))
+          (point (magit-point)))
+      (list (- (line-number-at-pos point)
                (line-number-at-pos start))
-            (- (point) (line-beginning-position))
+            (- point (line-beginning-position))
             (and (magit-hunk-section-p section)
                  (region-active-p)
                  (progn (goto-char (line-beginning-position))
                         (when  (looking-at "^[-+]") (forward-line))
                         (while (looking-at "^[ @]") (forward-line))
-                        (let ((beg (point)))
+                        (let ((beg point))
                           (cond ((looking-at "^[-+]")
                                  (forward-line)
                                  (while (looking-at "^[-+]") (forward-line))
diff --git a/lisp/magit-section.el b/lisp/magit-section.el
index 9a2b91e2f2..1bb6477a55 100644
--- a/lisp/magit-section.el
+++ b/lisp/magit-section.el
@@ -429,9 +429,39 @@ of this variable is set by `magit-insert-section' and you 
should
 never modify it.")
 (put 'magit-root-section 'permanent-local t)
 
+(defvar-local magit--context-menu-section nil "For internal use only.")
+
+(defvar magit--context-menu-buffer nil "For internal use only.")
+
+(defun magit-point ()
+  "Return point or the position where the context menu was invoked.
+When using the context menu, return the position the user clicked
+on, provided the current buffer is the buffer in which the click
+occured.  Otherwise return the same value as `point'."
+  (if magit--context-menu-section
+      (magit-menu-position)
+    (point)))
+
+(defun magit-thing-at-point (thing &optional no-properties)
+  "Return the THING at point or where the context menu was invoked.
+When using the context menu, return the thing the user clicked
+on, provided the current buffer is the buffer in which the click
+occured.  Otherwise return the same value as `thing-at-point'.
+For the meaning of THING and NO-PROPERTIES see that function."
+  (if-let ((pos (magit-menu-position)))
+      (save-excursion
+        (goto-char pos)
+        (thing-at-point thing no-properties))
+    (thing-at-point thing no-properties)))
+
 (defun magit-current-section ()
-  "Return the section at point."
-  (or (magit-section-at) magit-root-section))
+  "Return the section at point or where the context menu was invoked.
+When using the context menu, return the section that the user
+clicked on, provided the current buffer is the buffer in which
+the click occured.  Otherwise return the section at point."
+  (or magit--context-menu-section
+      (magit-section-at)
+      magit-root-section))
 
 (defun magit-section-at (&optional position)
   "Return the section at POSITION, defaulting to point."
@@ -510,9 +540,14 @@ The return value has the form (TYPE...)."
 
 (defun magit-section-context-menu (menu click)
   "Populate MENU with Magit-Section commands at CLICK."
-  (mouse-set-point click)
-  (magit-section-update-highlight t)
-  (when-let ((section (magit-section-at)))
+  (when-let ((section (save-excursion
+                        (unless (region-active-p)
+                          (mouse-set-point click))
+                        (magit-section-at))))
+    (unless (region-active-p)
+      (setq magit--context-menu-buffer (current-buffer))
+      (setq magit--context-menu-section section)
+      (magit-section-update-highlight t))
     (when (magit-section-content-p section)
       (define-key-after menu [magit-section-toggle]
         `(menu-item
@@ -582,9 +617,39 @@ the expression (magit-menu-format-desc DESC) for that.  See
   (when (and (stringp desc) (string-match-p "%[tTvsmMx]" desc))
     (setq desc (list 'magit-menu-format-desc desc)))
   (define-key-after keymap key
-    `(menu-item ,desc ,def ,@props)
+    `( menu-item ,desc ,def ,@props
+       ;; Without this, the keys for point would be shown instead
+       ;; of the relevant ones from where the click occured.
+       ,@(and (not (region-active-p))
+              (list :keys
+                    (lambda ()
+                      (or (ignore-errors
+                            (save-excursion
+                              (goto-char (magit-menu-position))
+                              (key-description (where-is-internal def nil t))))
+                          "")))))
     after))
 
+(defun magit-menu-position ()
+  "Return the position where the context-menu was invoked.
+If the current command wasn't invoked using the context-menu,
+then return nil."
+  (and magit--context-menu-section
+       (ignore-errors
+         (posn-point (event-start (aref (this-command-keys-vector) 0))))))
+
+(defun magit-menu-highlight-point-section ()
+  (setq magit-section-highlight-force-update t)
+  (if (eq (current-buffer) magit--context-menu-buffer)
+      (setq magit--context-menu-section nil)
+    (if-let ((window (get-buffer-window magit--context-menu-buffer)))
+        (with-selected-window window
+          (setq magit--context-menu-section nil)
+          (magit-section-update-highlight))
+      (with-current-buffer magit--context-menu-buffer
+        (setq magit--context-menu-section nil))))
+  (setq magit--context-menu-buffer nil))
+
 (defvar magit--plural-append-es '(branch))
 
 (cl-defgeneric magit-menu-common-value (_section)
@@ -1477,12 +1542,29 @@ evaluated its BODY.  Admittedly that's a bit of a hack."
 (defvar-local magit-section-unhighlight-sections nil)
 
 (defun magit-section-pre-command-hook ()
+  (when (and (not (bound-and-true-p transient--prefix))
+             (or magit--context-menu-buffer
+                 magit--context-menu-section)
+             (not (eq (ignore-errors
+                        (event-basic-type (aref (this-command-keys) 0)))
+                      'mouse-3)))
+    ;; This is the earliest opportunity to clean up after an aborted
+    ;; context-menu because that neither causes the command that created
+    ;; the menu to abort nor some abortion hook to be run.  It is not
+    ;; possible to update highlighting before the first command invoked
+    ;; after the menu is aborted.  Here we can only make sure it is
+    ;; updated afterwards.
+    (magit-menu-highlight-point-section))
   (setq magit-section-pre-command-region-p (region-active-p))
   (setq magit-section-pre-command-section (magit-current-section)))
 
 (defun magit-section-post-command-hook ()
-  (unless (memq this-command '(magit-refresh magit-refresh-all))
-    (magit-section-update-highlight)))
+  (unless (bound-and-true-p transient--prefix)
+    (when (or magit--context-menu-buffer
+              magit--context-menu-section)
+      (magit-menu-highlight-point-section))
+    (unless (memq this-command '(magit-refresh magit-refresh-all))
+      (magit-section-update-highlight))))
 
 (defun magit-section-deactivate-mark ()
   (setq magit-section-highlight-force-update t))



reply via email to

[Prev in Thread] Current Thread [Next in Thread]