unofficial mirror of emacs-devel@gnu.org 
 help / color / mirror / code / Atom feed
From: "David De La Harpe Golden" <david.delaharpe.golden@gmail.com>
To: emacs-devel@gnu.org
Subject: Re: Improving X selection?
Date: Wed, 17 Oct 2007 00:29:02 +0100	[thread overview]
Message-ID: <8e24944a0710161629r1ec1afadj60352dc92c264217@mail.gmail.com> (raw)
In-Reply-To: <E1IhdlH-0002z3-ML@fencepost.gnu.org>

[-- Attachment #1: Type: text/plain, Size: 3354 bytes --]

Hi,

Attached please find a stab at adjusting emacs selection interactions
to be comfy for naive users.  Not saying it's the best way for
experienced text-processing emacs X11 users, who might well  _like_
the fact killing interacts with PRIMARY, but this is how I made emacs
"feel" more like other apps, and interact particularly nicely (maybe)
with freedesktop.org compliant ones.

N.B. I can certainly see the attractions of having more
complex/powerful/traditional mouse-highlight and
PRIMARY/SECONDARY/CLIPBOARD and kill-ring interactions for more
advanced users, this was just a stab at making things act like a naive
user might expect, I just present it as one data point - an expanded
and cleaned up X11 selections handling system might want to permit
something like this as one possible configuration in its configuration
space.


Explanation:

0.  Transient mark mode => t . Of course.

1. mouse-drag-copy-region => nil.   You can set this to nil to prevent
the mouse highlight operation insta-copying the region to the kill
ring. To get to the kill ring with the mouse, you have to highlight
with the mouse (setting mark and point and making region active), then
press C-w/M-w to kill.  This obviously makes kill ring interaction
"feel" more like a usual clipboard within emacs, and does away with an
(imo confusing) difference between keyboard highlighting and mouse
highlighting.

2. However, killing still interacts with PRIMARY unless you nullify
interprogram-cut-function and interprogram-paste-function like
mouse-sel mode does, or better, adjust the functions to go to
CLIPBOARD rather than PRIMARY.  So let's do the latter.
By analogy with x-select-enable-clipboard, introduce
x-select-enable-primary to x-select-text and
x-cut-buffer-or-selection-value.   When x-select-enable-primary is nil
and x-select-enable-clipboard is t, then C-w/M-w go to CLIPBOARD, C-y
only pulls from CLIPBOARD (yeah, I'm ignoring cut buffers here).
Richard has just said he _likes_ C-y pulling in primary, but anyway, I
think it should pull in CLIPBOARD and only clipboard, so adjust  too -
the option is there, by enabling x-select-enable-primary, to allow
pulling from PRIMARY.

(Next thought: should the customs be split into incoming and outgoing? :-) )

(BTW, x-select-text has the comment  "gildea@stop.mail-abuse.org says
it's not desirable to put kills in the clipboard."  Well. Um.)

3. But now, the mouse highlighted region is not propagated to PRIMARY,
as propagation to selection is currently done by
copy-region-to-kill-ring which calls interprogram-cut-function, and if
mouse-drag-copy-region is nil, that isn't called.

So, to get other-X11-app-like freedesktop.org-like behaviour, you
really need to hook, so that when the mark is active, region becomes
PRIMARY (whether form the keyboard or from the mouse - Observe what
e.g. oowriter or firefox does with keyboard-highlighted (usual
shortuct: shift+arrow-keys) regions - they set PRIMARY, just like when
you highlight with the mouse in them.

Easy enough with a hook calling x-set-selection with
activate-mark-hook (which is also called when the region changes
shape).

4. But then, what about middle-button yanking?  What should that do?
Just insert PRIMARY if it exists, IMHO.   Not that since PRIMARY is
being set by the hook in 3, this also works merrily for emacs-to-emacs
mouseing.

[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: dgxselect.el --]
[-- Type: text/x-emacs-lisp; name="dgxselect.el", Size: 7167 bytes --]

; FIXME: Do as a minor mode like mouse-sel / mouse-copy / mouse-drag ???

; 0

(setq transient-mark-mode t)

; 1

(setq mouse-drag-copy-region nil)

;2 

;;; Like x-select-enable-clipboard

(defcustom x-select-enable-primary t
  "Non-nil means cutting and pasting uses the primary selection."
  :type 'boolean
  :group 'killing)

(setq x-select-enable-clipboard t)

(setq x-select-enable-primary nil)


;;; modified from term/x-win.el
;;; cut and pasted, change is basically just an extra (when...

(defun x-select-text* (text &optional push)
  "Make TEXT, a string, the primary or clipboard or both X selection,
depending on value of x-select-enable-clipboard and x-select-enable-primary
Also, set the value of X cut buffer 0, for backward compatibility
with older X applications."
  ;; Don't send the cut buffer too much text.
  ;; It becomes slow, and if really big it causes errors.
  (cond ((>= (length text) x-cut-buffer-max)
	 (x-set-cut-buffer "" push)
	 (setq x-last-selected-text-cut ""
	       x-last-selected-text-cut-encoded ""))
	(t
	 (setq x-last-selected-text-cut text
	       x-last-cut-buffer-coding 'iso-latin-1
	       x-last-selected-text-cut-encoded
	       ;; ICCCM says cut buffer always contain ISO-Latin-1
	       (encode-coding-string text 'iso-latin-1))
	 (x-set-cut-buffer x-last-selected-text-cut-encoded push)))
  (when x-select-enable-primary
    (x-set-selection 'PRIMARY text)
    (setq x-last-selected-text-primary text))
  (when x-select-enable-clipboard
    (x-set-selection 'CLIPBOARD text)
    (setq x-last-selected-text-clipboard text))
  )


;;; modified from term/x-win.el
;;; cut and pasted, change is basically just an extra (when ...

;; Return a value of one of the current X selections.
;; Consult the selections, and the cut buffer.  Treat empty strings
;; as if they were unset.
;; If this function is called twice and finds the same text,
;; it returns nil the second time.  This is so that a single
;; selection won't be added to the kill ring over and over.
(defun x-cut-buffer-or-selection-value* ()
  (let (clip-text primary-text cut-text)
    (when x-select-enable-clipboard
      (setq clip-text (x-selection-value 'CLIPBOARD))
      (if (string= clip-text "") (setq clip-text nil))

      ;; Check the CLIPBOARD selection for 'newness', is it different
      ;; from what we remebered them to be last time we did a
      ;; cut/paste operation.
      (setq clip-text
	    (cond;; check clipboard
	     ((or (not clip-text) (string= clip-text ""))
	      (setq x-last-selected-text-clipboard nil))
	     ((eq      clip-text x-last-selected-text-clipboard) nil)
	     ((string= clip-text x-last-selected-text-clipboard)
	      ;; Record the newer string,
	      ;; so subsequent calls can use the `eq' test.
	      (setq x-last-selected-text-clipboard clip-text)
	      nil)
	     (t
	      (setq x-last-selected-text-clipboard clip-text))))
      )
    (when x-select-enable-primary
      (setq primary-text (x-selection-value 'PRIMARY))
      ;; Check the PRIMARY selection for 'newness', is it different
      ;; from what we remebered them to be last time we did a
      ;; cut/paste operation.
      (setq primary-text
	    (cond;; check primary selection
	     ((or (not primary-text) (string= primary-text ""))
	      (setq x-last-selected-text-primary nil))
	     ((eq      primary-text x-last-selected-text-primary) nil)
	     ((string= primary-text x-last-selected-text-primary)
	      ;; Record the newer string,
	      ;; so subsequent calls can use the `eq' test.
	      (setq x-last-selected-text-primary primary-text)
	      nil)
	     (t
	      (setq x-last-selected-text-primary primary-text))))
      )

    (setq cut-text (x-get-cut-buffer 0))

    ;; Check the x cut buffer for 'newness', is it different
    ;; from what we remebered them to be last time we did a
    ;; cut/paste operation.
    (setq cut-text
	  (let ((next-coding (or next-selection-coding-system 'iso-latin-1)))
	    (cond;; check cut buffer
	     ((or (not cut-text) (string= cut-text ""))
	      (setq x-last-selected-text-cut nil))
	     ;; This short cut doesn't work because x-get-cut-buffer 	 
	     ;; always returns a newly created string. 	 
	     ;; ((eq      cut-text x-last-selected-text-cut) nil) 	 
	     ((and (string= cut-text x-last-selected-text-cut-encoded)
		   (eq x-last-cut-buffer-coding next-coding))
	      ;; See the comment above.  No need of this recording. 	 
	      ;; Record the newer string, 	 
	      ;; so subsequent calls can use the `eq' test. 	 
	      ;; (setq x-last-selected-text-cut cut-text) 	 
	      nil)
	     (t
	      (setq x-last-selected-text-cut-encoded cut-text
		  x-last-cut-buffer-coding next-coding
		  x-last-selected-text-cut
		  ;; ICCCM says cut buffer always contain ISO-Latin-1, but
		  ;; use next-selection-coding-system if not nil.
		  (decode-coding-string 
		   cut-text next-coding))))))

    ;; As we have done one selection, clear this now.
    (setq next-selection-coding-system nil)

    ;; At this point we have recorded the current values for the
    ;; selection from clipboard (if we are supposed to) primary,
    ;; and cut buffer.  So return the first one that has changed
    ;; (which is the first non-null one).
    ;;
    ;; NOTE: There will be cases where more than one of these has
    ;; changed and the new values differ.  This indicates that
    ;; something like the following has happened since the last time
    ;; we looked at the selections: Application X set all the
    ;; selections, then Application Y set only one or two of them (say
    ;; just the cut-buffer).  In this case since we don't have
    ;; timestamps there is no way to know what the 'correct' value to
    ;; return is.  The nice thing to do would be to tell the user we
    ;; saw multiple possible selections and ask the user which was the
    ;; one they wanted.
    ;; This code is still a big improvement because now the user can
    ;; futz with the current selection and get emacs to pay attention
    ;; to the cut buffer again (previously as soon as clipboard or
    ;; primary had been set the cut buffer would essentially never be
    ;; checked again).
    (or clip-text primary-text cut-text)
    ))



(setf interprogram-cut-function 'x-select-text*)
(setf interprogram-paste-function 'x-cut-buffer-or-selection-value*)

; 3

; x-set-selection nil == primary. 
(add-hook 'activate-mark-hook 
	  (function (lambda ()
		      (x-set-selection nil (buffer-substring (region-beginning) (region-end))))))


; 4

;;; based on mouse.el/mouse-yank-secondary

(defun mouse-yank-primary (click)
  "Insert the primary selection at the position clicked on.
Move point to the end of the inserted text.
If `mouse-yank-at-point' is non-nil, insert at point
regardless of where you click."
  (interactive "e")
  ;; Give temporary modes such as isearch a chance to turn off.
  (run-hooks 'mouse-leave-buffer-hook)
  (or mouse-yank-at-point (mouse-set-point click))
  (let ((secondary (x-get-selection 'PRIMARY)))
    (if secondary
        (insert (x-get-selection 'PRIMARY))
      (error "No primary selection"))))

(global-set-key [mouse-2] 'mouse-yank-primary)

[-- Attachment #3: Type: text/plain, Size: 142 bytes --]

_______________________________________________
Emacs-devel mailing list
Emacs-devel@gnu.org
http://lists.gnu.org/mailman/listinfo/emacs-devel

  reply	other threads:[~2007-10-16 23:29 UTC|newest]

Thread overview: 100+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2007-10-15 10:20 Improving X selection? Horsley, Tom
2007-10-15 11:06 ` Jan Djärv
2007-10-16  4:10 ` Richard Stallman
2007-10-16 23:29   ` David De La Harpe Golden [this message]
2007-10-17  1:05     ` David De La Harpe Golden
2007-12-25 21:13     ` Richard Stallman
2008-01-28 19:52       ` David De La Harpe Golden
2008-01-29  0:59         ` David De La Harpe Golden
2008-02-01 19:15           ` David De La Harpe Golden
2008-02-02  0:17             ` David De La Harpe Golden
2008-02-03 11:38               ` David De La Harpe Golden
2008-02-03 12:44                 ` Jan D.
2008-02-03 13:12                   ` David De La Harpe Golden
2008-02-04 21:02                     ` David De La Harpe Golden
2008-02-05  3:38                       ` David De La Harpe Golden
2008-02-05  7:08                       ` Jan Djärv
2008-02-07  3:57                         ` David De La Harpe Golden
2008-02-07  4:23                           ` Miles Bader
2008-02-07  4:59                             ` David De La Harpe Golden
2008-02-07  9:07                           ` Jason Rumney
2008-02-07 16:32                             ` David De La Harpe Golden
2008-02-07 17:11                               ` David De La Harpe Golden
2008-02-07 17:13                               ` Jason Rumney
2008-02-07 19:46                                 ` Stefan Monnier
2008-02-10 18:42                                 ` Richard Stallman
2008-02-11 17:46                                   ` David De La Harpe Golden
2008-02-07 17:25                               ` Stefan Monnier
2008-02-07 17:39                                 ` David De La Harpe Golden
2008-02-07 17:51                                   ` David De La Harpe Golden
2008-02-07 19:54                                   ` Stefan Monnier
2008-02-07 15:14                           ` Stefan Monnier
2008-02-07 16:15                             ` David De La Harpe Golden
2008-02-07 18:01                               ` Stephen J. Turnbull
2008-02-07 18:07                                 ` David De La Harpe Golden
2008-02-07 19:21                                   ` Stephen J. Turnbull
2008-02-08  1:19                                     ` Miles Bader
2008-02-08  1:42                                       ` David De La Harpe Golden
2008-02-07 18:22                                 ` David De La Harpe Golden
2008-02-07 19:45                                   ` Stefan Monnier
2008-02-07 20:39                                     ` David De La Harpe Golden
2008-02-07 21:25                                       ` Stephen J. Turnbull
2008-02-07 21:41                                         ` David De La Harpe Golden
2008-02-08  0:22                                           ` Stephen J. Turnbull
2008-02-08  1:26                                             ` David De La Harpe Golden
2008-02-07 22:43                                       ` Stefan Monnier
2008-02-08  2:50                                         ` David De La Harpe Golden
2008-02-08 13:26                                           ` OT [was Re: Improving X selection?] Tom Horsley
2008-02-08 15:30                                             ` David De La Harpe Golden
2008-02-08 16:07                                               ` OT Stefan Monnier
2008-02-08 16:43                                                 ` OT David De La Harpe Golden
2008-02-08 14:41                                           ` Improving X selection? Stefan Monnier
2008-02-08 15:21                                             ` David De La Harpe Golden
2008-02-17  3:38                                             ` David De La Harpe Golden
2008-02-17  3:55                                               ` David De La Harpe Golden
2008-02-07 21:01                                     ` Tom Horsley
2008-02-07 21:18                                       ` David De La Harpe Golden
2008-02-07 21:36                                         ` Tom Horsley
2008-02-07 21:40                                           ` David De La Harpe Golden
2008-02-07 22:51                                       ` Stefan Monnier
     [not found]                                 ` <8e24944a0802071042u43d68f04pc8492ad8ce07aa18@mail.gmail.com>
2008-02-07 18:44                                   ` Fwd: " David De La Harpe Golden
2008-02-03 16:18             ` Richard Stallman
2008-02-03 18:29               ` David De La Harpe Golden
2008-02-05  5:58               ` David De La Harpe Golden
2008-02-05  6:23                 ` Miles Bader
2008-02-05  6:56                   ` David De La Harpe Golden
2008-02-03 16:18           ` Richard Stallman
     [not found] <20071012105022.6c8b174a@tweety>
2007-10-14 16:29 ` Richard Stallman
2007-10-14 17:25   ` Jeremy Maitin-Shepard
2007-10-15  6:19     ` Jan Djärv
2007-10-15  6:21       ` Jan Djärv
2007-10-15  6:41       ` Eli Zaretskii
2007-10-15  6:55       ` Miles Bader
2007-10-15  8:16         ` Jan Djärv
2007-10-15 14:21       ` Stefan Monnier
2007-10-15 18:30       ` Richard Stallman
2007-10-15 19:26         ` Jeremy Maitin-Shepard
2007-10-15 20:03           ` Andreas Schwab
2007-10-15 20:22             ` Jeremy Maitin-Shepard
2007-10-16  8:02               ` Frank Schmitt
2007-10-16  7:27           ` Jan Djärv
2007-10-16 10:08             ` René Kyllingstad
2007-10-16 13:15               ` Stefan Monnier
2008-08-18 15:29                 ` René Kyllingstad
2008-08-18 18:47                   ` David De La Harpe Golden
2008-08-18 19:16                 ` David Hansen
2008-08-19  8:06                   ` Frank Schmitt
2008-08-25 15:34                     ` Juri Linkov
2008-08-25 15:56                       ` Frank Schmitt
2008-08-28 17:45                         ` David De La Harpe Golden
2008-08-28 17:58                           ` Frank Schmitt
2008-08-28 18:19                             ` David De La Harpe Golden
2008-08-29  5:53                               ` David Hansen
2008-08-30  4:08                                 ` David De La Harpe Golden
2008-08-31  7:41                                   ` David Hansen
2008-08-20 22:41                   ` David De La Harpe Golden
2008-08-25 15:34                     ` Juri Linkov
2008-08-26  3:09                       ` David Hansen
2008-08-26  8:03                         ` David De La Harpe Golden
2008-08-26  8:41                           ` David Hansen
2007-10-16  7:26         ` Jan Djärv

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

  List information: https://www.gnu.org/software/emacs/

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=8e24944a0710161629r1ec1afadj60352dc92c264217@mail.gmail.com \
    --to=david.delaharpe.golden@gmail.com \
    --cc=emacs-devel@gnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
Code repositories for project(s) associated with this public inbox

	https://git.savannah.gnu.org/cgit/emacs.git

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).