bug-gnu-emacs
[Top][All Lists]
Advanced

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

bug#27530: patch to cut and copy secondary


From: Tak Kunihiro
Subject: bug#27530: patch to cut and copy secondary
Date: Tue, 05 Sep 2017 12:11:04 +0900 (JST)

I found the secondary selection is very useful.  I sent a patch on
June 2017 and Drew inferred importance of commands to utilize the
secondary selection.

> IMO, the first, and simplest, improvement to add to Emacs is
> a way to create and yank the secondary selection using only
> the keyboard, not the mouse.  My guess is that the reason
> more users do not use the secondary selection is that there
> are no keyboard keybindings for it.

I found that the exchange of primary and secondary can be implemented
into C-x C-x as `mouse-exchange-point-and-mark-secondary'.

  (global-set-key [remap exchange-point-and-mark] 
'mouse-exchange-point-and-mark-secondary)

The function `mouse-exchange-point-and-mark-secondary' exchanges `mark
and point' and secondary.  When there is neither primary nor
secondary, it behaves as `exchange-point-and-mark'.  By doing this, no
revision is necessary for functions that react to region.
 
Here I send a revised patch that only applied to lisp/mouse.el to
utilize the secondary selection more. Please consider this patch to be
applied.



# Change log

2017-09-05  Tak Kunihiro  <address@hidden>

       Add a function to exchange the point and the mark, and the secondary 
selection.

       * lisp/mouse.el (mouse-exchange-point-and-mark-secondary): Exchange
        the point and the mark, and the secondary selection.
       (mouse-secondary-exists-p): Return if the secondary 
       selection exists in current buffer.
       (mouse-set-primary-from-secondary): Set the region to text in the 
       secondary selection.
       (mouse-set-secondary-from-primary): Set the secondary selection to 
       text in the region.


# Patch

diff --git a/mouse.260.el b/mouse.el
old mode 100644
new mode 100755
index 2fbaaad..505546f
--- a/mouse.260.el
+++ b/mouse.el
@@ -1916,6 +1916,71 @@ CLICK position, kill the secondary selection."
         (> (length str) 0)
         (gui-set-selection 'SECONDARY str))))
 
+(defun mouse-exchange-point-and-mark-secondary (&optional arg)
+  "Exchange the point and the mark, and the secondary selection.
+When the mark is active, this exchanges the point and the mark
+then creates the secondary selection from the primary selection.
+When the mark is not active but the secondary selection exists,
+this restores the primary selection from the secondary selection."
+  ;; (global-set-key [remap exchange-point-and-mark] 
'mouse-exchange-point-and-mark-secondary)
+  (interactive "P")
+  (cond
+   ((region-active-p)            ; Do not care pre-existing secondary.
+    (mouse-set-secondary-from-primary))
+   ((mouse-secondary-exists-p)          ; When no primary exists.
+    (mouse-set-primary-from-secondary))
+   (t nil))                             ; No primary and no secondary.
+  (exchange-point-and-mark arg))
+
+(defun mouse-secondary-exists-p ()
+  "Return if the secondary selection exists in current buffer.
+When exists, this returns start and end of the secondary selection."
+  (let ((buf (overlay-buffer mouse-secondary-overlay))
+        (beg (overlay-start mouse-secondary-overlay))
+        (end (overlay-end mouse-secondary-overlay)))
+    (when (and buf beg end
+               (equal buf (current-buffer))
+               (/= beg end))
+      (list beg end))))
+
+(defun mouse-set-primary-from-secondary ()
+  "Set the region to text in the secondary selection.
+This works when the secondary selection exists and the region
+does not exist in current buffer.  The mouse-secondary-overlay
+will be deleted."
+  (interactive)
+  (let ((secondary-to-kill (and (not (region-active-p))
+                                (mouse-secondary-exists-p))))
+    ;; Delete overlay even on different buffer.
+    ;; Deletion should be later than obtaining location.
+    (delete-overlay mouse-secondary-overlay)
+    (when secondary-to-kill
+      (let* ((pos0 (car secondary-to-kill))
+             (pos1 (cadr secondary-to-kill))
+             ;; Restore point to closer position.
+             (is-point-front (< (point) (/ (+ pos0 pos1) 2))))
+        (push-mark (if is-point-front pos1 pos0) t t)
+        (goto-char (if is-point-front pos0 pos1))))))
+
+(defun mouse-set-secondary-from-primary ()
+  "Set the secondary selection to text in the region.
+When region does not exists, set mouse-secondary-start to the point.
+When point is in the secondary selection, do nothing."
+  (interactive)
+  (cond
+   ((region-active-p) ; Create mouse-secondary-overlay from region.
+    (delete-overlay mouse-secondary-overlay)
+    (move-overlay mouse-secondary-overlay (region-beginning) (region-end)))
+   ((member 'secondary-selection ; Do nothing.
+            (mapcar (lambda (xxx) (overlay-get xxx 'face))
+                    (overlays-at (point)))))
+   (t (delete-overlay mouse-secondary-overlay) ; Create mouse-secondary-start 
from point.
+      (push-mark (point))
+      (setq mouse-secondary-start (make-marker))
+      (move-marker mouse-secondary-start (point)))))
+
 
 (defcustom mouse-buffer-menu-maxlen 20
   "Number of buffers in one pane (submenu) of the buffer menu.





reply via email to

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