]> git.eshelyaron.com Git - emacs.git/commitdiff
Improve behavior of `lost-selection-mode' with multiple buffers
authorPo Lu <luangruo@yahoo.com>
Mon, 11 Jul 2022 11:36:01 +0000 (19:36 +0800)
committerPo Lu <luangruo@yahoo.com>
Mon, 11 Jul 2022 11:36:12 +0000 (19:36 +0800)
* 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
lisp/select.el
src/keyboard.c

index 526bda283c30fd7a1eedcc758a54f99c72b2f0f2..afe0f115c5a4f93bdc4784b4a1ec54703c76aeb1 100644 (file)
--- 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
index 6002b2615e171d97fe0c54b7402eb781ef9ceaba..2d501f207f18e044bf259bc93913024104e12d1e 100644 (file)
@@ -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)))
 
 \f
 ;; Functions to convert the selection into various other selection types.
index 7c13ac96114eb149a26a17fa9b194c5b65ac3bfe..1d505c13be3fbd04043a82b97418cebef194218d 100644 (file)
@@ -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);
 }