emacs-diffs
[Top][All Lists]
Advanced

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

master 6f57fb71a5: Improve behavior of `lost-selection-mode' with multip


From: Po Lu
Subject: master 6f57fb71a5: Improve behavior of `lost-selection-mode' with multiple buffers
Date: Mon, 11 Jul 2022 07:36:22 -0400 (EDT)

branch: master
commit 6f57fb71a50a8b2ac8163828a2cecb394bb52d06
Author: Po Lu <luangruo@yahoo.com>
Commit: Po Lu <luangruo@yahoo.com>

    Improve behavior of `lost-selection-mode' with multiple buffers
    
    * etc/NEWS: Announce new hook `post-select-region-hook'.
    
    * lisp/select.el (lost-selection-last-region-buffer): New
    variable.
    (lost-selection-post-select-region-function): New function.
    Deactivate the mark if the buffer changed.
    (lost-selection-mode): Add new hook.
    
    * src/keyboard.c (command_loop_1): Run that hook when
    appropriate.
    (syms_of_keyboard): New hook `post-select-region-hook'.
---
 etc/NEWS       |  4 ++++
 lisp/select.el | 44 ++++++++++++++++++++++++++++++++++++--------
 src/keyboard.c | 12 ++++++++++++
 3 files changed, 52 insertions(+), 8 deletions(-)

diff --git a/etc/NEWS b/etc/NEWS
index 526bda283c..afe0f115c5 100644
--- a/etc/NEWS
+++ b/etc/NEWS
@@ -2665,6 +2665,10 @@ them towards or away from each other.
 This hook is run before 'x-popup-menu' is about to display a
 deck-of-cards menu on screen.
 
+** New hook 'post-select-region-hook'.
+This hook is run immediately after 'select-active-regions' causes the
+region to be set as the primary selection.
+
 ** New function 'buffer-match-p'.
 Check if a buffer satisfies some condition.  Some examples for
 conditions can be regular expressions that match a buffer name, a
diff --git a/lisp/select.el b/lisp/select.el
index 6002b2615e..2d501f207f 100644
--- a/lisp/select.el
+++ b/lisp/select.el
@@ -479,6 +479,24 @@ are not available to other programs."
 ;; Minor mode to make losing ownership of PRIMARY behave more like
 ;; other X programs.
 
+(defvar lost-selection-last-region-buffer nil
+  "The last buffer from which the region was selected.")
+
+(defun lost-selection-post-select-region-function (_text)
+  "Handle the region being selected into PRIMARY.
+If the current buffer is different from the last buffer,
+deactivate the mark in every other buffer.
+TEXT is ignored."
+  (when (not (eq lost-selection-last-region-buffer
+                 (current-buffer)))
+    (dolist (buffer (buffer-list))
+      (unless (or (string-match-p "^ "
+                                  (buffer-name buffer))
+                  (eq buffer (current-buffer)))
+        (with-current-buffer buffer
+          (deactivate-mark t))))
+    (setq lost-selection-last-region-buffer (current-buffer))))
+
 (defun lost-selection-function (selection)
   "Handle losing of ownership of SELECTION.
 If SELECTION is `PRIMARY', deactivate the mark in every
@@ -496,22 +514,32 @@ non-temporary buffer."
 
 When this is enabled, selecting some text in another program will
 cause the mark to be deactivated in all buffers, mimicking the
-behavior of most X Windows programs."
+behavior of most X Windows programs.
+
+Selecting text in a buffer that ends up changing the primary
+selection will also cause the mark to be deactivated in all other
+buffers."
   :global t
   :group 'x
   (if lost-selection-mode
-      (cond ((featurep 'x) (add-hook 'x-lost-selection-functions
-                                     #'lost-selection-function))
-            ((featurep 'pgtk) (add-hook 'pgtk-lost-selection-functions
-                                        #'lost-selection-function))
-            ((featurep 'haiku) (add-hook 'haiku-lost-selection-functions
-                                         #'lost-selection-function)))
+      (progn
+        (cond ((featurep 'x) (add-hook 'x-lost-selection-functions
+                                       #'lost-selection-function))
+              ((featurep 'pgtk) (add-hook 'pgtk-lost-selection-functions
+                                          #'lost-selection-function))
+              ((featurep 'haiku) (add-hook 'haiku-lost-selection-functions
+                                           #'lost-selection-function)))
+        (add-hook 'post-select-region-hook
+                  #'lost-selection-post-select-region-function))
     (cond ((featurep 'x) (remove-hook 'x-lost-selection-functions
                                       #'lost-selection-function))
           ((featurep 'pgtk) (remove-hook 'pgtk-lost-selection-functions
                                          #'lost-selection-function))
           ((featurep 'haiku) (remove-hook 'haiku-lost-selection-functions
-                                          #'lost-selection-function)))))
+                                          #'lost-selection-function)))
+    (remove-hook 'post-select-region-hook
+                 #'lost-selection-post-select-region-function)
+    (setq lost-selection-last-region-buffer nil)))
 
 
 ;; Functions to convert the selection into various other selection types.
diff --git a/src/keyboard.c b/src/keyboard.c
index 7c13ac9611..1d505c13be 100644
--- a/src/keyboard.c
+++ b/src/keyboard.c
@@ -1590,9 +1590,12 @@ command_loop_1 (void)
                {
                  Lisp_Object txt
                    = call1 (Vregion_extract_function, Qnil);
+
                  if (XFIXNUM (Flength (txt)) > 0)
                    /* Don't set empty selections.  */
                    call2 (Qgui_set_selection, QPRIMARY, txt);
+
+                 CALLN (Frun_hook_with_args, Qpost_select_region_hook, txt);
                }
 
              if (current_buffer != prev_buffer || MODIFF != prev_modiff)
@@ -12080,6 +12083,9 @@ syms_of_keyboard (void)
   DEFSYM (Qpre_command_hook, "pre-command-hook");
   DEFSYM (Qpost_command_hook, "post-command-hook");
 
+  /* Hook run after the region is selected.  */
+  DEFSYM (Qpost_select_region_hook, "post-select-region-hook");
+
   DEFSYM (Qundo_auto__add_boundary, "undo-auto--add-boundary");
   DEFSYM (Qundo_auto__undoably_changed_buffers,
           "undo-auto--undoably-changed-buffers");
@@ -13028,6 +13034,12 @@ not recorded.  The non-nil value countermands 
`inhibit--record-char',
 which see.  */);
   record_all_keys = false;
 
+  DEFVAR_LISP ("post-select-region-hook", Vpost_select_region_hook,
+    doc: /* Abnormal hook run after the region is selected.
+This usually happens as a result of `select-active-regions'.  The hook
+is called with one argument, the string that was selected.  */);;
+  Vpost_select_region_hook = Qnil;
+
   pdumper_do_now_and_after_load (syms_of_keyboard_for_pdumper);
 }
 



reply via email to

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