* RE: Improving X selection?
@ 2007-10-15 10:20 Horsley, Tom
2007-10-15 11:06 ` Jan Djärv
2007-10-16 4:10 ` Richard Stallman
0 siblings, 2 replies; 66+ messages in thread
From: Horsley, Tom @ 2007-10-15 10:20 UTC (permalink / raw)
To: Eli Zaretskii, Jan Djärv; +Cc: rms, jeremy, emacs-devel
>> I am very opposed to any solution that drags in any selection I explicitly
>> does not paste into Emacs. For example, if I want to paste CLIPBOARD,
>> PRIMARY
>> may be a very large selection. Over a slow link, getting PRIMARY also makes
>> Emacs unresponsive for several seconds.
>
>This just means that not all users will like the proposal, and
>therefore we should have an option to let the users decide what they
>want. The option should probably be tristate, as the current behavior
>could have its zealots as well, who will hate the change. Maybe even
>4 different values, see below.
Actually, I was sort of thinking that once the basic support
for returning multiple selection strings was implemented, an
X specific change could be devised that would introduce a
configurable variable something like:
x-paste-what-selections
which could be a list of 'CLIPBOARD, 'PRIMARY, etc.
This would even allow emacs to interact with custom selections
from custom apps by adding new non-standard selection names to
the list (not that I think that is really likely anyone would
actually use it :-).
^ permalink raw reply [flat|nested] 66+ messages in thread
* Re: Improving X selection? 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 1 sibling, 0 replies; 66+ messages in thread From: Jan Djärv @ 2007-10-15 11:06 UTC (permalink / raw) To: Horsley, Tom; +Cc: Eli Zaretskii, rms, jeremy, emacs-devel Horsley, Tom skrev: >>> I am very opposed to any solution that drags in any selection I explicitly >>> does not paste into Emacs. For example, if I want to paste CLIPBOARD, >>> PRIMARY >>> may be a very large selection. Over a slow link, getting PRIMARY also makes >>> Emacs unresponsive for several seconds. >> This just means that not all users will like the proposal, and >> therefore we should have an option to let the users decide what they >> want. The option should probably be tristate, as the current behavior >> could have its zealots as well, who will hate the change. Maybe even >> 4 different values, see below. > > Actually, I was sort of thinking that once the basic support > for returning multiple selection strings was implemented, an > X specific change could be devised that would introduce a > configurable variable something like: > > x-paste-what-selections > > which could be a list of 'CLIPBOARD, 'PRIMARY, etc. > That would have to be something like: x-paste-what-selections-with-menubar x-paste-what-selections-with-toolbar x-paste-what-selections-with-keys x-paste-what-selections-with-mouse to be useful, i.e. able to support the freedesktop model. Jan D. ^ permalink raw reply [flat|nested] 66+ messages in thread
* Re: Improving X selection? 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 1 sibling, 1 reply; 66+ messages in thread From: Richard Stallman @ 2007-10-16 4:10 UTC (permalink / raw) To: Horsley, Tom; +Cc: eliz, jan.h.d, jeremy, emacs-devel Actually, I was sort of thinking that once the basic support for returning multiple selection strings was implemented, an X specific change could be devised that would introduce a configurable variable something like: There is no reason to hesitate before implementing the basic patch that you described, which only makes it POSSIBLE for the function to return multiple strings. ^ permalink raw reply [flat|nested] 66+ messages in thread
* Re: Improving X selection? 2007-10-16 4:10 ` Richard Stallman @ 2007-10-16 23:29 ` David De La Harpe Golden 2007-10-17 1:05 ` David De La Harpe Golden 2007-12-25 21:13 ` Richard Stallman 0 siblings, 2 replies; 66+ messages in thread From: David De La Harpe Golden @ 2007-10-16 23:29 UTC (permalink / raw) To: emacs-devel [-- 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 ^ permalink raw reply [flat|nested] 66+ messages in thread
* Re: Improving X selection? 2007-10-16 23:29 ` David De La Harpe Golden @ 2007-10-17 1:05 ` David De La Harpe Golden 2007-12-25 21:13 ` Richard Stallman 1 sibling, 0 replies; 66+ messages in thread From: David De La Harpe Golden @ 2007-10-17 1:05 UTC (permalink / raw) To: emacs-devel If you've done the stuff in my previous mail, another IMHO useful change (that I use but I didn't include in the previous mail because it is a little more confusing if you don't expect it) is to make current-kill propagate its return back out via interprogram-cut-function if N > zero, and do-not-move is nil, and interprogram-cut-function is set. Then, emacs acts a bit like a clipboard history manager or pigeonholes - you can cut/copy in another X11 application A, C-y into emacs, cut/copy in another X11 application B, C-y into emacs, (etc... ). Then, in emacs cycle between the various cuts now in the emacs kill ring with M-y, then when you find the right one, it can be pasted back into an external X11 application directly since it's already in CLIPBOARD (assuming previous mail). Not too different in end result to just copying to a scratch buffer from the various apps and then selectively copying back out from it, but hey. e.g. ; based on simple.el/current-kill (defun current-kill (n &optional do-not-move) "Rotate the yanking point by N places, and then return that kill. If N is zero, `interprogram-paste-function' is set, and calling it returns a string, then that string is added to the front of the kill ring and returned as the latest kill. If N > zero, `interprogram-cut-function' is set, and do-not-move is nil, then also call the `interprogram-cut-function' with the latest kill - i.e. propagate it back out to the host environment clipboard. If optional arg DO-NOT-MOVE is non-nil, then don't actually move the yanking point; just return the Nth kill forward." (let ((interprogram-paste (and (= n 0) interprogram-paste-function (funcall interprogram-paste-function)))) (if interprogram-paste (progn ;; Disable the interprogram cut function when we add the new ;; text to the kill ring, so Emacs doesn't try to own the ;; selection, with identical text. (let ((interprogram-cut-function nil)) (kill-new interprogram-paste)) interprogram-paste) (or kill-ring (error "Kill ring is empty")) (let ((ARGth-kill-element (nthcdr (mod (- n (length kill-ring-yank-pointer)) (length kill-ring)) kill-ring))) (unless do-not-move (setq kill-ring-yank-pointer ARGth-kill-element) (when (and (> n 0) interprogram-cut-function) (funcall interprogram-cut-function (car ARGth-kill-element)))) (car ARGth-kill-element))))) ^ permalink raw reply [flat|nested] 66+ messages in thread
* Re: Improving X selection? 2007-10-16 23:29 ` David De La Harpe Golden 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 1 sibling, 1 reply; 66+ messages in thread From: Richard Stallman @ 2007-12-25 21:13 UTC (permalink / raw) To: David De La Harpe Golden; +Cc: emacs-devel Please forgive the delay in this response. It was not easy for me to read and understand your message, and I was rather rushed when it arrived, so I put it off. Now I have more time. If I understand right, your scheme is that mouse clicks should set and access the primary selection, but not the kill ring or the clipboard; meanwhile, the kill ring keystroke commands should access the clipboard in parallel with the kill ring. Did I understand correctly? I would not be entirely happy with that, because I would rather have some way to interact with the primary selection from the keyboard. However, I don't use selections very much in Emacs anyway, so this might not be very important. In any case, it can't hurt to add the new option x-select-enable-primary, and your other changes, as options disabled by default. I've done that in the trunk. Thank you. The big question is the proposal to change the default. I'm interested in hearing other people's opinions about this. If you've done the stuff in my previous mail, another IMHO useful change (that I use but I didn't include in the previous mail because it is a little more confusing if you don't expect it) is to make current-kill propagate its return back out via interprogram-cut-function if N > zero, and do-not-move is nil, and interprogram-cut-function is set. That added idea sounds good. I installed that in the trunk, under the control of another option. ^ permalink raw reply [flat|nested] 66+ messages in thread
* Re: Improving X selection? 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 0 siblings, 1 reply; 66+ messages in thread From: David De La Harpe Golden @ 2008-01-28 19:52 UTC (permalink / raw) To: rms, emacs-devel On 25/12/2007, Richard Stallman <rms@gnu.org> wrote: > Please forgive the delay in this response. It was not easy for me to > read and understand your message, and I was rather rushed when it > arrived, so I put it off. Now I have more time. > Thanks for applying the changes, and argh, in turn, please forgive me! I don't like the strange gmail web interface (particularly when applied to a high-traffic lists...l), only just found your reply :-( > If I understand right, your scheme is that mouse clicks should set > and access the primary selection, but not the kill ring or the clipboard; > meanwhile, the kill ring keystroke commands should access the clipboard > in parallel with the kill ring. > Did I understand correctly? > Essentially, but see *** about setting of the primary selection. > I would not be entirely happy with that, because I would rather have > some way to interact with the primary selection from the keyboard. *** Well, indeed. In part 3 of the hack, where I used activate-mark-hook (used in transient-mark-mode), by the description of activate-mark-hook, I was expecting activate-mark-hook to be called and therefore primary to be set whenever the mouse IOR the keyboard was used to set or adjust the active region and transient-mark-mode was on, but it doesn't seem to quite work as intended (not sure as yet whether that's my fault or a bug, should investigate further I guess). If it were working as I expected, it would reflect the behaviour of other recent X11 applications, where using the keyboard to highlight sets primary just like using the mouse does. I realise you're probably not using transient-mark-mode, though. But if x-select-enable-primary is non-nil, then x-select-text* propagates back out to primary, so you can still affect primary from the keyboard if you want, just use different settings. Even more flexibility (and potential for confusion...) might be to have 4 (6? - secondary :-) separate x-select-enable-[primary|clipboard]-for-[cut|paste] settings, in case people want things squirted out to primary but not sucked in from it and so on. ^ permalink raw reply [flat|nested] 66+ messages in thread
* Re: Improving X selection? 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-03 16:18 ` Richard Stallman 0 siblings, 2 replies; 66+ messages in thread From: David De La Harpe Golden @ 2008-01-29 0:59 UTC (permalink / raw) To: rms, emacs-devel On 28/01/2008, David De La Harpe Golden <david.delaharpe.golden@gmail.com> wrote: > > I would not be entirely happy with that, because I would rather have > > some way to interact with the primary selection from the keyboard. > > *** Well, indeed. In part 3 of the hack, where I used > activate-mark-hook (used in transient-mark-mode), by the description > of activate-mark-hook, I was expecting activate-mark-hook to be called > and therefore primary to be set whenever the mouse IOR the keyboard > was used to set or adjust the active region and transient-mark-mode > was on, Okay, more nearly on same page now, see the "select-active-regions" you introduced equivalent to the hook*. So I'll stop calling it the hook now. Anyway, it's not happening in some circumstances. * Maybe might want an interprogram-highlight-function to indirect through like interprogram-[cut|paste]-function, rather than embedding a direct call to x-set-selection, which I presume doesn't work on non-X11 ? Though of course, on platforms other that X11, users probably don't expect highlight-middlebutton copy/paste to work interprogram like it does on X11 in the first place... ^ permalink raw reply [flat|nested] 66+ messages in thread
* Re: Improving X selection? 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 16:18 ` Richard Stallman 2008-02-03 16:18 ` Richard Stallman 1 sibling, 2 replies; 66+ messages in thread From: David De La Harpe Golden @ 2008-02-01 19:15 UTC (permalink / raw) To: rms, emacs-devel [-- Attachment #1: Type: text/plain, Size: 999 bytes --] Attached patch introduces an interprogram-highlight-function and extends values of x-select-enable-clipboard / x-select-enable-primary in an (I think) useful manner*. The descriptions of the customizations may be overly verbose. Another mail to follow about making select-active-regions work. [This is all still separate to but not incompatible with the idea of having interprogram-paste-function be capable of returning more than one value.] * Note that since switching to trunk following unicode2 merge, w32-vars.el is now being loaded on my linux system, not clear on why (multi-tty?) - and it also contained an alternate x-select-enable-clipboard definition , which strikes me as even stranger, but I don't know about w32 (don't even have microsoft windows) - the patch just comments it out, not clear on what the right thing to do is, or why w32 is having anything to do with x x-select-* in the first place (surely it has its own w32-select-* for its interprogram-cut/paste functions?) [-- Warning: decoded text below may be mangled, UTF-8 assumed --] [-- Attachment #2: enhanced-x-selections.diff --] [-- Type: text/x-diff; name=enhanced-x-selections.diff, Size: 19205 bytes --] Index: lisp/simple.el =================================================================== RCS file: /sources/emacs/emacs/lisp/simple.el,v retrieving revision 1.899 diff -U 8 -r1.899 simple.el --- lisp/simple.el 1 Feb 2008 16:01:05 -0000 1.899 +++ lisp/simple.el 1 Feb 2008 19:09:20 -0000 @@ -2562,16 +2562,34 @@ programs. The function takes one or two arguments. The first argument, TEXT, is a string containing the text which should be made available. The second, optional, argument PUSH, has the same meaning as the similar argument to `x-set-cut-buffer', which see.") +(defvar interprogram-highlight-function nil + "Function to call to make an active region available to other progams. + +In addition to clibpoard cutting and pasting (see `interprogram-cut-function' +and `interprogram-paste-function'), some window systems (okay, one +window system, X11) provide a mechanism whereby text merely highlighted +in one application may be immediately inserted into another. +This variable holds a function that Emacs calls whenever +text is notionally highlighted in emacs - i.e. there is an active +region (see `transient-mark-mode'). The function will only be +called when `select-active-regions' is also set. + +The function takes one or two arguments, +The first argument, TEXT, is a string containing +the text that should be made available. +The second, optional, argument PUSH, has the same meaning as the +similar argument to `x-set-cut-buffer', which see.") + (defvar interprogram-paste-function nil "Function to call to get text cut from other programs. Most window systems provide some sort of facility for cutting and pasting text between the windows of different programs. This variable holds a function that Emacs calls to obtain text that other programs have provided for pasting. @@ -3346,18 +3364,19 @@ (let ((beg (point))) (forward-line 1) (delete-region beg (point)))." (if pos (progn (setq mark-active t) (run-hooks 'activate-mark-hook) (and select-active-regions - (x-set-selection - nil (buffer-substring (region-beginning) (region-end)))) + interprogram-highlight-function + (funcall interprogram-highlight-function + (buffer-substring (region-beginning) (region-end)))) (set-marker (mark-marker) pos (current-buffer))) ;; Normally we never clear mark-active except in Transient Mark mode. ;; But when we actually clear out the mark value too, ;; we must clear mark-active in any mode. (setq mark-active nil) (run-hooks 'deactivate-mark-hook) (set-marker (mark-marker) nil))) Index: lisp/w32-vars.el =================================================================== RCS file: /sources/emacs/emacs/lisp/w32-vars.el,v retrieving revision 1.19 diff -U 8 -r1.19 w32-vars.el --- lisp/w32-vars.el 8 Jan 2008 20:44:48 -0000 1.19 +++ lisp/w32-vars.el 1 Feb 2008 19:09:21 -0000 @@ -144,18 +144,21 @@ (repeat :inline t (choice :tag "" (const :tag "Separator" ("")) (list :tag "Font Entry" (string :tag "Menu text") (string :tag "Font"))))))) :group 'w32) -(defcustom x-select-enable-clipboard t - "*Non-nil means cutting and pasting uses the clipboard. -This is in addition to the primary selection." - :type 'boolean - :group 'killing) +;; Uh. Does this belong here? It's also in +;; term/x-win.el and now has an extended definition there +;; +;; (defcustom x-select-enable-clipboard t +;; "*Non-nil means cutting and pasting uses the clipboard. +;; This is in addition to the primary selection." +;; :type 'boolean +;; :group 'killing) (provide 'w32-vars) ;;; arch-tag: ee2394fb-9db7-4c15-a8f0-66b47f4a2bb1 ;;; w32-vars.el ends here Index: lisp/term/x-win.el =================================================================== RCS file: /sources/emacs/emacs/lisp/term/x-win.el,v retrieving revision 1.222 diff -U 8 -r1.222 x-win.el --- lisp/term/x-win.el 1 Feb 2008 16:01:25 -0000 1.222 +++ lisp/term/x-win.el 1 Feb 2008 19:09:24 -0000 @@ -2140,55 +2140,179 @@ This is the actual text stored in the X cut buffer.") (defvar x-last-cut-buffer-coding 'iso-latin-1 "The coding we last used to encode/decode the text from the X cut buffer") (defvar x-cut-buffer-max 20000 ; Note this value is overridden below. "Max number of characters to put in the cut buffer. It is said that overlarge strings are slow to put into the cut buffer.") -(defcustom x-select-enable-clipboard nil - "Non-nil means cutting and pasting uses the clipboard. -This is in addition to, but in preference to, the primary selection." - :type 'boolean - :group 'killing) - -(defcustom x-select-enable-primary t - "Non-nil means cutting and pasting uses the primary selection." - :type 'boolean - :group 'killing) +(defcustom x-select-enable-clipboard '(:cut :paste) +"What cut/copy/paste/highlight ops should involve CLIPBOARD. + +In X11, CLIPBOARD is normally associated with 'clipboard cut/copy/paste' +style data interchange. + +Cut/Copy: Set if Killing (e.g. C-w/M-w) in Emacs should place text in the +CLIPBOARD X11 selection, i.e. if you want to paste killed text into other +programs on your desktop with the other programs' clipboard paste +function (typically something like C-v in those programs) + +Paste: Set if Yanking (e.g. C-y) in Emacs should check the clipboard +for text placed there with other programs' clipboard cut or copy +functions (typically something like C-x or C-c in those programs) + +Highlight: Set if merely highlighting text (setting the active region) +in Emacs should immediately put it in the clipboard, if +`select-active-regions' is also set. This is unusual for recent X11 +applications, typically highlighted text is placed in the PRIMARY X11 +selection, for 'highlight/middlebutton' style X11 transfer. +See `x-select-enable-primary'. + +It is recommended to unset `mouse-drag-copy-region' and +set `transient-mark-mode' if Highlight is set here." + +:type '(choice (const :tag "None" nil) + (const :tag "All" t) + (set :tag "Choose" (const :tag "Cut/Copy" :cut) + (const :tag "Paste" :paste) + (const :tag "Highlight" :highlight))) +:group 'killing) + +(defcustom x-select-enable-primary '(:highlight) +"What cut/copy/paste/highlight ops should involve PRIMARY. + +In X11, PRIMARY is associated with 'highlight/middlebutton-insert' style +data interchange. + +Cut/Copy: Set if Killing (e.g. C-w/M-w) in emacs should place text in the +PRIMARY X11 selection. i.e. if you want to paste killed text into other +programs on your desktop with the other programs' primary insertion +function (typically a middle-button-click). This is not usual for X11 +applications, typically Cut/Copied text is placed in the CLIPBOARD X11 +selection, for clipboard-style X11 transfer. +See `x-select-enable-clipboard' + +Paste: Set if Yanking (e.g. C-y) in emacs should check the primary selection +for text placed there with other programs' primary selection +functions (typically highlighting the text in other X11 programs makes it +available as the primary selection). It is not usual in X11 to do so, however +it may be convenient to do so in emacs, as it reduces mousing, allowing easy +keyboard insertion of the primary selection. Note that if both +`x-select-enable-clipboard' and this have Paste set, the clipboard +currently takes precendence when yanking. + +Highlight: Set if merely highlighting text (an active region) in emacs should +immediately put it in the primary selection, if `select-active-regions' is +set. This is usual for recent X11 programs, and allows you to insert the text +into the other program with their primary insertion function (typically +middle-button-click). + +It is recommended to unset `mouse-drag-copy-region' and +set `transient-mark-mode' if Highlight is set here." + +:type '(choice (const :tag "None" nil) + (const :tag "All" t) + (set :tag "Choose" (const :tag "Cut/Copy" :cut) + (const :tag "Paste" :paste) + (const :tag "Highlight" :highlight))) +:group 'killing) + + +(defcustom x-select-enable-cutbuffer nil + "What cut/copy/paste/highlight ops shold involve legacy Cut Buffer 0. + +In X, cut buffers have long been superseded by clipboard and primary +selections. However, some old X programs use them. If you +need to exchange data between emacs and such programs via +X cut buffers, you may want to set this to a non-nil value. + +Cut/Copy: Set if Killing (e.g. C-w/M-w) in emacs should +place text into X Cut Buffer 0 + +Paste: Set if Yanking (e.g. C-y) in Emacs should check +X Cut Buffer 0 for text. + +Highlight: Set if merely highlighting text (an active region) +in emacs should immediately put it in X Cut Buffer 0, if +`select-active-regions' is also set. + +It is recommended to unset `mouse-drag-copy-region' and +set `transient-mark-mode' if Highlight is set here." + +:type '(choice (const :tag "None" nil) + (const :tag "All" t) + (set :tag "Choose" (const :tag "Cut/Copy" :cut) + (const :tag "Paste" :paste) + (const :tag "Highlight" :highlight))) +:group 'killing) + + +(defun x-select-text-for-op (op text &optional push) + "Make TEXT, a string, the primary and/or clipboard X selection. + +This function matches OP against `x-select-enable-primary' +and `x-select-enable-clipboard'. OP must be one of :cut +or :highlight, corresponding to use as an `interprogram-cut-function' +or `interprogram-highlight-function' + +Also may set the value of X cut buffer 0, for backward compatibility +with older X applications, matching OP against `x-select-enable-cutbuffer' -(defun x-select-text (text &optional push) - "Make TEXT, a string, the primary X selection. -Also, set the value of X cut buffer 0, for backward compatibility -with older X applications. gildea@stop.mail-abuse.org says it's not desirable to put kills in the clipboard." ;; With multi-tty, this function may be called from a tty frame. (when (eq (framep (selected-frame)) 'x) - ;; 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 + (when (or (eq x-select-enable-cutbuffer t) + (member op x-select-enable-cutbuffer)) + ;; 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 (or (eq x-select-enable-primary t) + (member op x-select-enable-primary)) (x-set-selection 'PRIMARY text) (setq x-last-selected-text-primary text)) - (when x-select-enable-clipboard + (when (or (eq x-select-enable-clipboard t) + (member op x-select-enable-clipboard)) (x-set-selection 'CLIPBOARD text) (setq x-last-selected-text-clipboard text)))) + +(defun x-select-text (text &optional push) + "Make TEXT, a string, the primary and/or clipboard X selection (for cut). + +Also may set the value of X cut buffer 0, for backward compatibility +with older X applications. + +This function is suitable as an `interprogram-cut-function'. +This function just calls `x-select-text-for-op' with OP :cut" + (x-select-text-for-op :cut text push)) + + +(defun x-select-text-for-highlight (text &optional push) + "Make TEXT, a string, the primary and/or clipboard X selection (for highlight). + +Also may set the value of X cut buffer 0, for backward compatibility +with older X applications. + +This function is suitable as an `interprogram-highlight-function'. +This function is calls `x-select-text-for-op' with OP `:highlight'" + (x-select-text-for-op :highlight text push)) + + (defvar x-select-request-type nil "*Data type request for X selection. The value is one of the following data types, a list of them, or nil: `COMPOUND_TEXT', `UTF8_STRING', `STRING', `TEXT' If the value is one of the above symbols, try only the specified type. @@ -2226,17 +2350,18 @@ ;; 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 () ;; With multi-tty, this function may be called from a tty frame. (when (eq (framep (selected-frame)) 'x) (let (clip-text primary-text cut-text) - (when x-select-enable-clipboard + (when (or (eq x-select-enable-clipboard t) + (member :paste 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 @@ -2245,17 +2370,18 @@ ((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 + (when (or (eq x-select-enable-primary t) + (member :paste 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)) @@ -2263,47 +2389,49 @@ ((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)))))) + (when (or (eq x-select-enable-cutbuffer t) + (member :paste x-select-enable-cutbuffer)) + (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) + ;; 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 @@ -2321,16 +2449,17 @@ ;; primary had been set the cut buffer would essentially never be ;; checked again). (or clip-text primary-text cut-text) ))) ;; Arrange for the kill and yank functions to set and check the clipboard. (setq interprogram-cut-function 'x-select-text) (setq interprogram-paste-function 'x-cut-buffer-or-selection-value) +(setq interprogram-highlight-function 'x-select-text-for-highlight) (defun x-clipboard-yank () "Insert the clipboard contents, or the last stretch of killed text." (interactive "*") (let ((clipboard-text (x-selection-value 'CLIPBOARD)) (x-select-enable-clipboard t)) (if (and clipboard-text (> (length clipboard-text) 0)) (kill-new clipboard-text)) ^ permalink raw reply [flat|nested] 66+ messages in thread
* Re: Improving X selection? 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 16:18 ` Richard Stallman 1 sibling, 1 reply; 66+ messages in thread From: David De La Harpe Golden @ 2008-02-02 0:17 UTC (permalink / raw) To: rms, emacs-devel [-- Attachment #1: Type: text/plain, Size: 1134 bytes --] On 01/02/2008, David De La Harpe Golden wrote: > Another mail to follow about making select-active-regions work. Problem with select-active-regions is obvious: if you want it to work with both keyboard and mouse, it's not enough to reset the x11 selection when the mark is reset, it needs to be reset when the point is reset too, or the selection and active region will drift out of sync until the next mark reset. All well and good, but how to fix it? Well, I can naively introduce post-point-motion function (as attached*), but it's kind of intrusive and a potential performance problem, though probably unnoticeable on modern/fast machines/networks. There might be a better way to do it? (I thought about propagating selection when idle, but sudden selection inaccuracy when you go too fast would be annoying. post-command-hook doesn't work either (I think). Not sure how else to do it.) * Note that I'm not really up to speed on emacs internals, especially the C side and GC requirements when calling lisp from C. (Some mouse.el interactions need additional options too I think - yet another mail to follow with them...) [-- Warning: decoded text below may be mangled, UTF-8 assumed --] [-- Attachment #2: select-active-regions-when-point-moves-too.diff --] [-- Type: text/x-diff; name=select-active-regions-when-point-moves-too.diff, Size: 5413 bytes --] diff -NarU 10 emacs-exs/lisp/simple.el emacs/lisp/simple.el --- emacs-exs/lisp/simple.el 2008-02-01 22:40:31.000000000 +0000 +++ emacs/lisp/simple.el 2008-02-01 23:31:52.000000000 +0000 @@ -3340,20 +3340,63 @@ (transient-mark-mode (setq mark-active nil) (run-hooks 'deactivate-mark-hook)))) (defcustom select-active-regions nil "If non-nil, an active region automatically becomes the window selection." :type 'boolean :group 'killing :version "23.1") + +;; Do we want to provide a general post-point-motion-hook ? +;; Easily abused, would at least have to come with dire warning +;; about performance implications of anything added. +;; +(defvar post-point-motion-hook nil + "Hook called after point movement. + +Keep hooks short, sweet and FAST, or better yet, don't use this +at all. Hooks here should NOT try to affect point position, +unless you want recursive trouble.") + +(defun post-point-motion () + "Internal Lisp function called after point movements. + +See e.g. `activate-mark-hook', `post-command-hook' and text properties +`point-entered' / `point-left' if you want to take action in +certain common point movement situations. + +`inhibit-point-motion-hooks' inhibits calling this +function and therefore anything it does. This function currently +just handles sending the highlighted regions to the window system +when the point is moved and `select-active-regions' is true" + + ;; Er. But Should inhibit-point-motion-hooks inhibit this? I just + ;; about argued myself into thinking it shouldt - if it shouldn't, + ;; change in C code intervals.c/set_point_both(), not here. + + (and select-active-regions + (region-active-p) + interprogram-highlight-function + (funcall interprogram-highlight-function + (buffer-substring (region-beginning) (region-end)))) + ;; activate-mark-hook is defined in its docstring to run + ;; after commands when the region may have changed, not just when + ;; the mark activates. Does moving the point + ;; and thus changing the region count as such a command - probably? + (and (region-active-p) + (run-hooks 'activate-mark-hook)) + ;; if you want post-point-motion-hook above... + (run-hooks 'post-point-motion-hook)) + + (defun set-mark (pos) "Set this buffer's mark to POS. Don't use this function! That is to say, don't use this function unless you want the user to see that the mark has moved, and you want the previous mark position to be lost. Normally, when a new mark is set, the old one should go on the stack. This is why most applications should use `push-mark', not `set-mark'. Novice Emacs Lisp programmers often try to use the mark for the wrong diff -NarU 10 emacs-exs/src/intervals.c emacs/src/intervals.c --- emacs-exs/src/intervals.c 2008-02-01 22:41:39.000000000 +0000 +++ emacs/src/intervals.c 2008-02-01 23:16:00.000000000 +0000 @@ -2050,20 +2050,23 @@ if (charpos > BUF_ZV (buffer) || charpos < BUF_BEGV (buffer)) abort (); have_overlays = (buffer->overlays_before || buffer->overlays_after); /* If we have no text properties and overlays, then we can do it quickly. */ if (NULL_INTERVAL_P (BUF_INTERVALS (buffer)) && ! have_overlays) { temp_set_point_both (buffer, charpos, bytepos); + if (NILP (Vinhibit_point_motion_hooks) && + FUNCTIONP (intern ("post-point-motion"))) + call0 (intern ("post-point-motion")); return; } /* Set TO to the interval containing the char after CHARPOS, and TOPREV to the interval containing the char before CHARPOS. Either one may be null. They may be equal. */ to = find_interval (BUF_INTERVALS (buffer), charpos); if (charpos == BUF_BEGV (buffer)) toprev = 0; else if (to && to->position == charpos) @@ -2087,20 +2090,23 @@ else if (buffer_point != BUF_PT (buffer)) fromprev = from, from = 0; else fromprev = from; /* Moving within an interval. */ if (to == from && toprev == fromprev && INTERVAL_VISIBLE_P (to) && ! have_overlays) { temp_set_point_both (buffer, charpos, bytepos); + if (NILP (Vinhibit_point_motion_hooks) && + FUNCTIONP (intern ("post-point-motion"))) + call0 (intern ("post-point-motion")); return; } original_position = charpos; /* If the new position is between two intangible characters with the same intangible property value, move forward or backward until a change in that property. */ if (NILP (Vinhibit_point_motion_hooks) && ((! NULL_INTERVAL_P (to) && ! NULL_INTERVAL_P (toprev)) @@ -2236,20 +2242,25 @@ call2 (leave_after, make_number (old_position), make_number (charpos)); if (! EQ (enter_before, leave_before) && !NILP (enter_before)) call2 (enter_before, make_number (old_position), make_number (charpos)); if (! EQ (enter_after, leave_after) && !NILP (enter_after)) call2 (enter_after, make_number (old_position), make_number (charpos)); } + + if (NILP (Vinhibit_point_motion_hooks) && + FUNCTIONP (intern ("post-point-motion"))) + call0 (intern ("post-point-motion")); + } \f /* Move point to POSITION, unless POSITION is inside an intangible segment that reaches all the way to point. */ void move_if_not_intangible (position) int position; { Lisp_Object pos; ^ permalink raw reply [flat|nested] 66+ messages in thread
* Re: Improving X selection? 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. 0 siblings, 1 reply; 66+ messages in thread From: David De La Harpe Golden @ 2008-02-03 11:38 UTC (permalink / raw) To: rms, emacs-devel [-- Attachment #1: Type: text/plain, Size: 2788 bytes --] On 02/02/2008, David De La Harpe Golden wrote: > (Some mouse.el interactions need additional options too I think - yet > another mail to follow with them...) See attached patch (n.b. depends on previously sent patch "enhanced-x-selection.diff", guess l should do an aggregate patch with all proposed stuff...) Goal here was mouse behaviour that fits in nicely with select-active-regions, three main issues (one for each button as it happens...): *** 1. mouse-set-point vs. select-active-regions issue: Add a deactivate-mark in mouse-set-point: This prevents copying different text than expected to primary when select-active-regions is true and you mouse-1 click to move the point (otherwise it ends up setting the X11 selection to the region between the mark and new place you clicked, which is not right). However blindly deactivating the mark when the mouse is used to set the point may be a bit too heavy-handed/sweeping, there may be subtleties I haven't spotted? *** 2. mouse-save-then-kill-copy-region: Similar to mouse-drag-copy-region, only for mouse-3 clicks rather than mouse-1 drags: allows mouse-save-then-kill to possibly: nil => merely adjust active region t => original behaviour: single-click: save double-click: kill. :double => require "one more click" over original behaviour, i .e. single click just for adjustment of region, double-click for kill ring save, and triple click for kill. Note that while select-active-regions is on, adjusting the active region might set the primary x11 selection, and if mouse-save-then-kill does interact with the kill ring, it might (indirectly) set the clipboard x11 selection via the interprogram-cut-function called by the kill routines. Not hugely happy with my ad-hoc changes to mouse-save-then-kill code to add this, I guess the function could be rewritten more clearly, but at least the "nil" new behaviour is need for mouse interaction to be unsurprising when select-active-region is on, and I then just thought the :double behaviour was a useful option to add. *** 3. mouse-yank-at-click-action, introduces X11-like lightweight insert operation, allows mouse-2 mouse-yank-at-click to possibly just paste in a selection from (introduced) interprogram-lightins-function (*) rather than yanking from kill ring. x-select-enable-[primary|clipboard|cutbuffer] customizations also expanded, added a fourth kind of operation, :lightins, to go with the X11 interprogram-lightins-function, that is to say x-cut-buffer-or-selection-value-for-lightins * interprogram-[cut|paste]-function and interprogram-[highlight|lightins]-function are notionally paired. (Of course in another sense cut/highlight being output from emacs functions and paste/lightins being input to emacs functions make pairs), yay for symmetry. [-- Warning: decoded text below may be mangled, UTF-8 assumed --] [-- Attachment #2: mouse-behaviours-nice-with-select-active-regions.diff --] [-- Type: text/x-diff; name=mouse-behaviours-nice-with-select-active-regions.diff, Size: 25536 bytes --] diff -NarU10 emacs-fsar/lisp/mouse.el emacs/lisp/mouse.el --- emacs-fsar/lisp/mouse.el 2008-02-02 02:07:23.000000000 +0000 +++ emacs/lisp/mouse.el 2008-02-03 11:34:47.000000000 +0000 @@ -653,24 +653,27 @@ ;; window too thin. (if (< (- x left -1) window-min-width) (setq x (+ left window-min-width -1))) ;; compute size change needed (setq growth (- x right -1)) (condition-case nil (adjust-window-trailing-edge window growth t) (error nil)))))))))) \f (defun mouse-set-point (event) - "Move point to the position clicked on with the mouse. + "Move point to the position clicked on with the mouse, deactivating +region beforehand. This should be bound to a mouse click event type." (interactive "e") (mouse-minibuffer-check event) + ; select-active-regions is misleading unless this happens + (deactivate-mark) ;; Use event-end in case called from mouse-drag-region. ;; If EVENT is a click, event-end and event-start give same value. (posn-set-point (event-end event))) (defvar mouse-last-region-beg nil) (defvar mouse-last-region-end nil) (defvar mouse-last-region-tick nil) (defun mouse-region-match () "Return non-nil if there's an active region that was set with the mouse." @@ -1349,34 +1352,57 @@ The text is saved in the kill ring, as with \\[kill-region]." (interactive "e") (mouse-minibuffer-check click) (let* ((posn (event-start click)) (click-posn (posn-point posn))) (select-window (posn-window posn)) (if (numberp click-posn) (kill-region (min (point) click-posn) (max (point) click-posn))))) +(defcustom mouse-yank-at-click-action :lightins + "Whether mouse-yank-at-click should do a real `yank' +or use `interprogram-lightins-function' to try an X11-middlebutton-style +sort of insert. + +Yank: a kill-ring yank, which may in turn call `interprogram-paste-function' + +LightIns: Call `interprogram-lightins-function', do not use kill ring" + + :type '(choice (const :tag "LightIns" :lightins) + (const :tag "Yank" :yank)) + :group 'mouse) + (defun mouse-yank-at-click (click arg) - "Insert the last stretch of killed text at the position clicked on. + "Insert the last stretch of killed text as if by \\[yank] at the + position clicked on, if `mouse-yank-at-click-action' is yank. + +If `mouse-yank-at-click-action' is lightins insert text +returned by `interprogram-lightins-function' without +involving kill ring. + Also move point to one end of the text thus inserted (normally the end), and set mark at the beginning. Prefix arguments are interpreted as with \\[yank]. If `mouse-yank-at-point' is non-nil, insert at point regardless of where you click." (interactive "e\nP") ;; 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)) - (setq this-command 'yank) (setq mouse-selection-click-count 0) - (yank arg)) + (cond ((eq mouse-yank-at-click-action :lightins) + (and interprogram-lightins-function + (insert (funcall 'interprogram-lightins-function)))) + (t + (setq this-command 'yank) + (yank arg)))) (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)) @@ -1429,83 +1455,134 @@ (let ((tail buffer-undo-list)) ;; Search back in buffer-undo-list for the string ;; that came from deleting one character. (while (and tail (not (stringp (car (car tail))))) (setq tail (cdr tail))) ;; Replace it with an entry for the entire deleted text. (and tail (setcar tail (cons (car kill-ring) (min beg end)))))) (undo-boundary)) +(defcustom mouse-save-then-kill-copy-region :double + "How should mouse-save-then-kill save then kill? +Never: only adjust active region, never kill. +Single: save on single click, kill on second click +Double: adjust active region on first click, save +on second, kill on third" + +:type '(choice (const :tag "Never" nil) + (const :tag "Single" t) + (const :tag "Double" :double)) +:group 'mouse) + + + (defun mouse-save-then-kill (click) "Save text to point in kill ring; the second time, kill the text. + +Behaviour depends on `mouse-save-then-kill-copy-region'. If that +is nil, clicking merely adjusts the region. If :double, single +clicking adjusts the region, double clicking saves text to kill +ring, triple clicking kills the text. If nil, +single clicking saves text to kill ring, double clicking kills. + If the text between point and the mouse is the same as what's at the front of the kill ring, this deletes the text. Otherwise, it adds the text to the kill ring, like \\[kill-ring-save], which prepares for a second click to delete the text. If you have selected words or lines, this command extends the selection through the word or line clicked on. If you do this again in a different position, it extends the selection again. -If you do this twice in the same position, the selection is killed." +If you do this twice (or three times if :double) in the same +position, the selection is killed. +" (interactive "e") (let ((before-scroll (with-current-buffer (window-buffer (posn-window (event-start click))) point-before-scroll))) (mouse-minibuffer-check click) (let ((click-posn (posn-point (event-start click))) ;; Don't let a subsequent kill command append to this one: ;; prevent setting this-command to kill-region. (this-command this-command)) (if (and (with-current-buffer (window-buffer (posn-window (event-start click))) (and (mark t) (> (mod mouse-selection-click-count 3) 0) ;; Don't be fooled by a recent click in some other buffer. (eq mouse-selection-click-count-buffer (current-buffer))))) + ;; moving by words/lines (if (not (and (eq last-command 'mouse-save-then-kill) (equal click-posn (car (cdr-safe (cdr-safe mouse-save-then-kill-posn)))))) ;; Find both ends of the object selected by this click. (let* ((range (mouse-start-end click-posn click-posn mouse-selection-click-count))) ;; Move whichever end is closer to the click. ;; That's what xterm does, and it seems reasonable. (if (< (abs (- click-posn (mark t))) (abs (- click-posn (point)))) (set-mark (car range)) (goto-char (nth 1 range))) - ;; We have already put the old region in the kill ring. - ;; Replace it with the extended region. - ;; (It would be annoying to make a separate entry.) - (kill-new (buffer-substring (point) (mark t)) t) + + (cond ((eq mouse-save-then-kill-copy-region t) ; save on first click + ;; We have already put the old region in the kill ring. + ;; Replace it with the extended region. + ;; (It would be annoying to make a separate entry.) + (kill-new (buffer-substring (point) (mark t)) t) + ;; Arrange for a repeated mouse-3 to kill this region. + (setq mouse-save-then-kill-posn + (list (car kill-ring) (point) click-posn))) + ((eq mouse-save-then-kill-copy-region :double) ; no save on first click + ;; no save on first click, but need to know region from first + ;; nil for saved kill ring top used to indicate limbo between second and third clicks + (setq mouse-save-then-kill-posn + (list nil (point) click-posn)))) (mouse-set-region-1) - ;; Arrange for a repeated mouse-3 to kill this region. - (setq mouse-save-then-kill-posn - (list (car kill-ring) (point) click-posn)) (mouse-show-mark)) - ;; If we click this button again without moving it, - ;; that time kill. - (mouse-save-then-kill-delete-region (mark) (point)) - (setq mouse-selection-click-count 0) - (setq mouse-save-then-kill-posn nil)) - (if (and (eq last-command 'mouse-save-then-kill) + (cond ((eq mouse-save-then-kill-copy-region t) ; kill on second click + ;; If we click this button again without moving it, + ;; that time kill. + (mouse-save-then-kill-delete-region (mark) (point)) + (setq mouse-selection-click-count 0) + (setq mouse-save-then-kill-posn nil)) + ((eq mouse-save-then-kill-copy-region :double) ;save on second/kill on third + (if (car-safe mouse-save-then-kill-posn) ; kill on third + (progn + (mouse-save-then-kill-delete-region (mark) (point)) + (setq mouse-selection-click-count 0) + (setq mouse-save-then-kill-posn nil)) + (progn ; save on second + (kill-new (buffer-substring (point) (mark t)) t) + (setq mouse-save-then-kill-posn + (list (car kill-ring) (point) click-posn))))))) + ;; moving by chars + (if (and (eq last-command 'mouse-save-then-kill) mouse-save-then-kill-posn - (eq (car mouse-save-then-kill-posn) (car kill-ring)) - (equal (cdr mouse-save-then-kill-posn) (list (point) click-posn))) - ;; If this is the second time we've called - ;; mouse-save-then-kill, delete the text from the buffer. - (progn - (mouse-save-then-kill-delete-region (point) (mark)) - ;; After we kill, another click counts as "the first time". - (setq mouse-save-then-kill-posn nil)) + (equal (cdr-safe mouse-save-then-kill-posn) (list (point) click-posn))) + (cond ((eq mouse-save-then-kill-copy-region t) ; kill on second click + ;; If this is the second time we've called + ;; mouse-save-then-kill, delete the text from the buffer. + (mouse-save-then-kill-delete-region (point) (mark)) + ;; After we kill, another click counts as "the first time". + (setq mouse-save-then-kill-posn nil)) + ((eq mouse-save-then-kill-copy-region :double) ; save on second / kill on third + (if (car-safe mouse-save-then-kill-posn) ; kill on third + (progn + (mouse-save-then-kill-delete-region (point) (mark)) + (setq mouse-save-then-kill-posn nil)) + (progn ; save on second + (kill-new (buffer-substring (point) (mark t)) t) + (setq mouse-save-then-kill-posn + (list (car kill-ring) (point) click-posn)))))) ;; This is not a repetition. ;; We are adjusting an old selection or creating a new one. (if (or (and (eq last-command 'mouse-save-then-kill) mouse-save-then-kill-posn) (and mark-active transient-mark-mode) (and (memq last-command '(mouse-drag-region mouse-set-region)) (or mark-even-if-inactive (not transient-mark-mode)))) ;; We have a selection or suitable region, so adjust it. @@ -1513,31 +1590,39 @@ (new (posn-point posn))) (select-window (posn-window posn)) (if (numberp new) (progn ;; Move whichever end of the region is closer to the click. ;; That is what xterm does, and it seems reasonable. (if (<= (abs (- new (point))) (abs (- new (mark t)))) (goto-char new) (set-mark new)) (setq deactivate-mark nil))) - (kill-new (buffer-substring (point) (mark t)) t)) + (and (eq mouse-save-then-kill-copy-region t) ; save on first click + (kill-new (buffer-substring (point) (mark t)) t))) ;; Set the mark where point is, then move where clicked. (mouse-set-mark-fast click) (if before-scroll (goto-char before-scroll)) (exchange-point-and-mark) ;Why??? --Stef - (kill-new (buffer-substring (point) (mark t)))) - (mouse-show-mark) + (and (eq mouse-save-then-kill-copy-region t) ; save on first click + (kill-new (buffer-substring (point) (mark t))))) + (cond ((eq mouse-save-then-kill-copy-region t) ; save on first click + (setq mouse-save-then-kill-posn + (list (car kill-ring) (point) click-posn))) + ((eq mouse-save-then-kill-copy-region :double) ; no save on first click + ;; no save on first click, but need to know region from first + ;; nil for saved kill ring top used to indicate limbo between second and third clicks + (setq mouse-save-then-kill-posn + (list nil (point) click-posn)))) (mouse-set-region-1) - (setq mouse-save-then-kill-posn - (list (car kill-ring) (point) click-posn))))))) + (mouse-show-mark)))))) \f (global-set-key [M-mouse-1] 'mouse-start-secondary) (global-set-key [M-drag-mouse-1] 'mouse-set-secondary) (global-set-key [M-down-mouse-1] 'mouse-drag-secondary) (global-set-key [M-mouse-3] 'mouse-secondary-save-then-kill) (global-set-key [M-mouse-2] 'mouse-yank-secondary) (defconst mouse-secondary-overlay (let ((ol (make-overlay (point-min) (point-min)))) (delete-overlay ol) diff -NarU10 emacs-fsar/lisp/simple.el emacs/lisp/simple.el --- emacs-fsar/lisp/simple.el 2008-02-02 02:07:19.000000000 +0000 +++ emacs/lisp/simple.el 2008-02-03 04:52:54.000000000 +0000 @@ -2603,20 +2603,52 @@ system supports multiple selections. The first string will be used as the pasted text, but the other will be placed in the kill ring for easy access via `yank-pop'. Note that the function should return a string only if a program other than Emacs has provided a string for pasting; if Emacs provided the most recent string, the function should return nil. If it is difficult to tell whether Emacs or some other program provided the current string, it is probably good enough to return nil if the string is equal (according to `string=') to the last text Emacs provided.") + +(defvar interprogram-lightins-function nil + "Function to call to get text made available for highlight-insertion from other programs. + +Some window systems (okay one window system, X11) provide a +facility for immediately inserting text highlighted in one program +into another, bypassing the clipboard. + +This variable holds a function that Emacs calls to obtain +text that other programs have provided for such 'lightweight +insertion'. The convention has developed on X11 +that this lightweight highlight/insertion should be entirely +independent from the clipboard proper. + +The function should be called with no arguments. If the function +returns nil, then no other program has provided such text. If the +function returns a string, then the caller of the function +\(usually `mouse-yank-at-click') will insert this string +into the buffer... without affecting the kill ring. This may +seem slightly strange, but is intended and now typical +behaviour on X11 desktops. If you DO want mouse-yank-at-click to +affect the kill ring, as it has done in the past in emacs, +adjust `mouse-yank-at-click-action' to have it use the kill +ring \(and thereby potentially `interprogram-paste-function'), which +on X11 at least \(the only relevant platform at the moment) can +in turn be adjusted to pull in PRIMARY as well as or instead of +CLIPBOARD via `x-select-enable-primary'. + +Note that the function should return a string if available +whether or not a program other than Emacs provided the string, +this is so that emacs->emacs highlight/lightins interactions +work as expected.") \f ;;;; The kill ring data structure. (defvar kill-ring nil "List of killed text sequences. Since the kill ring is supposed to interact nicely with cut-and-paste facilities offered by window systems, use of this variable should interact nicely with `interprogram-cut-function' and diff -NarU10 emacs-fsar/lisp/term/x-win.el emacs/lisp/term/x-win.el --- emacs-fsar/lisp/term/x-win.el 2008-02-02 02:07:32.000000000 +0000 +++ emacs/lisp/term/x-win.el 2008-02-03 05:49:25.000000000 +0000 @@ -2161,66 +2161,84 @@ functions (typically something like C-x or C-c in those programs) Highlight: Set if merely highlighting text (setting the active region) in Emacs should immediately put it in the clipboard, if `select-active-regions' is also set. This is unusual for recent X11 applications, typically highlighted text is placed in the PRIMARY X11 selection, for 'highlight/middlebutton' style X11 transfer. See `x-select-enable-primary'. It is recommended to unset `mouse-drag-copy-region' and -set `transient-mark-mode' if Highlight is set here." +set `transient-mark-mode' if Highlight is set here. + +LightIns: Set if the CLIPBOARD selection should be checked for +lightweight insert operations \( `mouse-yank-at-click' +with `mouse-yank-at-click-action' set to LightIns). This is not +customary on X11, and even if you do want the middle mouse +button (i.e. mouse-2 typically bound to mouse-yank-at-click) +to pull in the clipboard like historic emacs, it is likely you want +to set mouse-yank-at-click-action to Yank and set Paste here instead +so that the Kill Ring is side-effected by the operation. Clear as mud." :type '(choice (const :tag "None" nil) (const :tag "All" t) (set :tag "Choose" (const :tag "Cut/Copy" :cut) (const :tag "Paste" :paste) - (const :tag "Highlight" :highlight))) + (const :tag "Highlight" :highlight) + (const :tag "LightIns" :lightins))) :group 'killing) -(defcustom x-select-enable-primary '(:highlight) +(defcustom x-select-enable-primary '(:highlight :lightins) "What cut/copy/paste/highlight ops should involve PRIMARY. In X11, PRIMARY is associated with 'highlight/middlebutton-insert' style data interchange. Cut/Copy: Set if Killing (e.g. C-w/M-w) in emacs should place text in the PRIMARY X11 selection. i.e. if you want to paste killed text into other programs on your desktop with the other programs' primary insertion function (typically a middle-button-click). This is not usual for X11 applications, typically Cut/Copied text is placed in the CLIPBOARD X11 selection, for clipboard-style X11 transfer. See `x-select-enable-clipboard' Paste: Set if Yanking (e.g. C-y) in emacs should check the primary selection for text placed there with other programs' primary selection functions (typically highlighting the text in other X11 programs makes it available as the primary selection). It is not usual in X11 to do so, however it may be convenient to do so in emacs, as it reduces mousing, allowing easy keyboard insertion of the primary selection. Note that if both `x-select-enable-clipboard' and this have Paste set, the clipboard -currently takes precendence when yanking. +currently takes precendence when yanking. You might want to +set `mouse-yank-at-click-action' to Yank if you set this, rather than +setting LightIns here. Highlight: Set if merely highlighting text (an active region) in emacs should immediately put it in the primary selection, if `select-active-regions' is set. This is usual for recent X11 programs, and allows you to insert the text into the other program with their primary insertion function (typically middle-button-click). It is recommended to unset `mouse-drag-copy-region' and -set `transient-mark-mode' if Highlight is set here." +set `transient-mark-mode' if Highlight is set here. + +LightIns: Set if the PRIMARY selection should be checked for +lightweight insert operations \( `mouse-yank-at-click' +with `mouse-yank-at-click-action' set to LightIns). This is normal +on X11." :type '(choice (const :tag "None" nil) (const :tag "All" t) (set :tag "Choose" (const :tag "Cut/Copy" :cut) (const :tag "Paste" :paste) - (const :tag "Highlight" :highlight))) + (const :tag "Highlight" :highlight) + (const :tag "LightIns" :lightins))) :group 'killing) (defcustom x-select-enable-cutbuffer nil "What cut/copy/paste/highlight ops shold involve legacy Cut Buffer 0. In X, cut buffers have long been superseded by clipboard and primary selections. However, some old X programs use them. If you need to exchange data between emacs and such programs via X cut buffers, you may want to set this to a non-nil value. @@ -2229,27 +2247,32 @@ place text into X Cut Buffer 0 Paste: Set if Yanking (e.g. C-y) in Emacs should check X Cut Buffer 0 for text. Highlight: Set if merely highlighting text (an active region) in emacs should immediately put it in X Cut Buffer 0, if `select-active-regions' is also set. It is recommended to unset `mouse-drag-copy-region' and -set `transient-mark-mode' if Highlight is set here." +set `transient-mark-mode' if Highlight is set here. + +LightIns: Set if X Cut Buffer 0 should be checked for +lightweight insert operations \( `mouse-yank-at-click' +with `mouse-yank-at-click-action' set to LightIns)." :type '(choice (const :tag "None" nil) (const :tag "All" t) (set :tag "Choose" (const :tag "Cut/Copy" :cut) (const :tag "Paste" :paste) - (const :tag "Highlight" :highlight))) + (const :tag "Highlight" :highlight) + (const :tag "LightIns" :lightins))) :group 'killing) (defun x-select-text-for-op (op text &optional push) "Make TEXT, a string, the primary and/or clipboard X selection. This function matches OP against `x-select-enable-primary' and `x-select-enable-clipboard'. OP must be one of :cut or :highlight, corresponding to use as an `interprogram-cut-function' or `interprogram-highlight-function' @@ -2444,24 +2467,90 @@ ;; 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) ))) + +;; Return the value of the current X selection for a "lightweight insertion" +;; that is not intended to interact with the kill ring. No, really. +;; Consult the selection, and the cut buffer. Treat empty strings +;; as if they were unset. +;; If this function is called twice and finds the same text, +;; unlike x-cut-buffer-or-selection-value, it should return the same text. +;; See interprogram-lightins-function docstring... +(defun x-cut-buffer-or-selection-value-for-lightins () + ;; With multi-tty, this function may be called from a tty frame. + (when (eq (framep (selected-frame)) 'x) + (let (clip-text primary-text cut-text) + (when (or (eq x-select-enable-clipboard t) + (member :lightins x-select-enable-clipboard)) + (setq clip-text (x-selection-value 'CLIPBOARD)) + (if (string= clip-text "") (setq clip-text nil))) + + (when (or (eq x-select-enable-primary t) + (member :lightins x-select-enable-primary)) + (setq primary-text (x-selection-value 'PRIMARY))) + + (when (or (eq x-select-enable-cutbuffer t) + (member :lightins x-select-enable-cutbuffer)) + (setq cut-text (x-get-cut-buffer 0)) + ;; try to decode cut buffer. + (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 "")) + nil) + (t ;; 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) + ))) + + + + + ;; Arrange for the kill and yank functions to set and check the clipboard. (setq interprogram-cut-function 'x-select-text) (setq interprogram-paste-function 'x-cut-buffer-or-selection-value) (setq interprogram-highlight-function 'x-select-text-for-highlight) +(setq interprogram-lightins-function 'x-cut-buffer-or-selection-value-for-lightins) (defun x-clipboard-yank () "Insert the clipboard contents, or the last stretch of killed text." (interactive "*") (let ((clipboard-text (x-selection-value 'CLIPBOARD)) (x-select-enable-clipboard t)) (if (and clipboard-text (> (length clipboard-text) 0)) (kill-new clipboard-text)) (yank))) ^ permalink raw reply [flat|nested] 66+ messages in thread
* Re: Improving X selection? 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 0 siblings, 1 reply; 66+ messages in thread From: Jan D. @ 2008-02-03 12:44 UTC (permalink / raw) To: David De La Harpe Golden; +Cc: rms, emacs-devel David De La Harpe Golden wrote: > On 02/02/2008, David De La Harpe Golden wrote: >> (Some mouse.el interactions need additional options too I think - yet >> another mail to follow with them...) > > See attached patch (n.b. depends on previously sent patch > "enhanced-x-selection.diff", guess l should do an aggregate patch with > all proposed stuff...) > > Goal here was mouse behaviour that fits in nicely with > select-active-regions, three main issues (one for each button as it > happens...): > > > *** 1. mouse-set-point vs. select-active-regions issue: > > Add a deactivate-mark in mouse-set-point: This prevents copying > different text than expected to primary when select-active-regions is > true and you mouse-1 click to move the point (otherwise it ends up > setting the X11 selection to the region between the mark and new place > you clicked, which is not right). > > However blindly deactivating the mark when the mouse is used to set > the point may be a bit too heavy-handed/sweeping, there may be > subtleties I haven't spotted? > Are you saying that one can't set mark, move the point with the mouse and then do stuff like M-w, C-x C-x anymore? If so, I think that is totally unacceptable, it makes mouse-set-point almost unusable. Jan D. ^ permalink raw reply [flat|nested] 66+ messages in thread
* Re: Improving X selection? 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 0 siblings, 1 reply; 66+ messages in thread From: David De La Harpe Golden @ 2008-02-03 13:12 UTC (permalink / raw) To: Jan D.; +Cc: rms, emacs-devel On 03/02/2008, Jan D. <jan.h.d@swipnet.se> wrote: > David De La Harpe Golden wrote: > > *** 1. mouse-set-point vs. select-active-regions issue: > > > > Add a deactivate-mark in mouse-set-point: This prevents copying > > different text than expected to primary when select-active-regions is > > true and you mouse-1 click to move the point (otherwise it ends up > > setting the X11 selection to the region between the mark and new > > place you clicked, which is not right). > > > > However blindly deactivating the mark when the mouse is used to set > > the point may be a bit too heavy-handed/sweeping, there may be > > subtleties I haven't spotted? > > > > Are you saying that one can't set mark, move the point with the mouse > and then do stuff like M-w, C-x C-x anymore? If so, I think that is > totally unacceptable, it makes mouse-set-point almost unusable. > Well, agreed: It didn't really look like the right thing to do (do please consider the patches a starting point, they're surely not ready for merge), though N.B these three cases remain working: (a) one can set both the mark and point with the keyboard (b) or set both the mark and point at once with mouse-1-drag (c) or with the (patched) mouse-save-then-kill mouse-3-clicks to set or adjust region. It "only" causes a problem with mixed keyboard/mouse-1 i.e. (d) hit keyboard C-SPC to set mark and then use mouse-1-click (mouse-set-point) with the expectation of defining an active region. Uh. Did (d) work before? It probably did, I just don't have an unmutilated emacs to hand to check. ^ permalink raw reply [flat|nested] 66+ messages in thread
* Re: Improving X selection? 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 0 siblings, 2 replies; 66+ messages in thread From: David De La Harpe Golden @ 2008-02-04 21:02 UTC (permalink / raw) To: Jan D.; +Cc: rms, emacs-devel On 03/02/2008, David De La Harpe Golden wrote: > On 03/02/2008, Jan D. wrote: > > Are you saying that one can't set mark, move the point with the mouse > > and then do stuff like M-w, C-x C-x anymore? If so, I think that is > > totally unacceptable, it makes mouse-set-point almost unusable. > > > > Well, agreed: Or not... > It "only" causes a problem with mixed keyboard/mouse-1 i.e. > (d) hit keyboard C-SPC to set mark and then use mouse-1-click > (mouse-set-point) with the expectation of defining an active region. > > Uh. Did (d) work before? It probably did, I just don't have an > unmutilated emacs to hand to check. > No, it didn't work that way without the patch: when you mouse-set-point (mouse-1-click) in CVS emacs, the region deactivates anyway, which _is_ normal behaviour in X11 applications come to think of it (mouse-1-drag highlight some text in firefox, mouse-1-click somewhere else...). The insertion of deactivate-mark into mouse-set-point makes the region deactivate immediately before the point move rather than immediately afterward. That didn't matter before (because nothing was trying to propagate out the active region when the point moved), with select-active-regions the order of move-point/deactivate-mark vs. deactivate-mark/move-point during mouse-set-point is significant. Guess should next trace exactly where in the call stack the region deactivation is occurring in unpatched emacs. ^ permalink raw reply [flat|nested] 66+ messages in thread
* Re: Improving X selection? 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 1 sibling, 0 replies; 66+ messages in thread From: David De La Harpe Golden @ 2008-02-05 3:38 UTC (permalink / raw) To: Jan D.; +Cc: rms, emacs-devel [-- Attachment #1: Type: text/plain, Size: 923 bytes --] On 04/02/2008, David De La Harpe Golden wrote: > That didn't matter > before (because nothing was trying to propagate out the active region > when the point moved), with select-active-regions the order of > move-point/deactivate-mark vs. deactivate-mark/move-point during > mouse-set-point is significant. > > Guess should next trace exactly where in the call stack the region > deactivation is occurring in unpatched emacs. > Right. This happens (unconditionally as far as I can see) in mouse-drag-track, which happens on mouse down. Moving the deactivate-mark to happen before the initial point move (which mouse-drag-track does with mouse-set-point...) rather than after fixes the select-active-regions behaviour, and I doubt it matters much otherwise? [and avoids damaging mouse-set-point's behaviour for those who like to unbind dragging from the mouse and use different buttons to set the mark and point, say...] [-- Warning: decoded text below may be mangled, UTF-8 assumed --] [-- Attachment #2: mouse-drag-track-deactivate-mark-earlier.diff --] [-- Type: text/x-diff; name=mouse-drag-track-deactivate-mark-earlier.diff, Size: 1203 bytes --] Index: lisp/mouse.el =================================================================== RCS file: /sources/emacs/emacs/lisp/mouse.el,v retrieving revision 1.326 diff -u -r1.326 mouse.el --- lisp/mouse.el 8 Jan 2008 05:12:50 -0000 1.326 +++ lisp/mouse.el 5 Feb 2008 03:29:30 -0000 @@ -925,6 +925,11 @@ The region will be defined with mark and point, and the overlay will be deleted after return. DO-MOUSE-DRAG-REGION-POST-PROCESS should only be used by mouse-drag-region." + ;; this function defines a new region, so deactivate mark before first + ;; moving point, to avoid briefly resizing the previous active region + ;; if any. Such a brief resize can produce poor behaviour when + ;; select-active-regions is enabled. + (deactivate-mark) (mouse-minibuffer-check start-event) (setq mouse-selection-click-count-buffer (current-buffer)) (let* ((original-window (selected-window)) @@ -971,7 +976,6 @@ (mouse-move-drag-overlay mouse-drag-overlay start-point start-point click-count) (overlay-put mouse-drag-overlay 'window start-window) - (deactivate-mark) (let (event end end-point last-end-point) (track-mouse (while (progn ^ permalink raw reply [flat|nested] 66+ messages in thread
* Re: Improving X selection? 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 1 sibling, 1 reply; 66+ messages in thread From: Jan Djärv @ 2008-02-05 7:08 UTC (permalink / raw) To: David De La Harpe Golden; +Cc: rms, emacs-devel David De La Harpe Golden skrev: > On 03/02/2008, David De La Harpe Golden wrote: >> On 03/02/2008, Jan D. wrote: >>> Are you saying that one can't set mark, move the point with the mouse >>> and then do stuff like M-w, C-x C-x anymore? If so, I think that is >>> totally unacceptable, it makes mouse-set-point almost unusable. >>> >> Well, agreed: > > Or not... > >> It "only" causes a problem with mixed keyboard/mouse-1 i.e. >> (d) hit keyboard C-SPC to set mark and then use mouse-1-click >> (mouse-set-point) with the expectation of defining an active region. >> >> Uh. Did (d) work before? It probably did, I just don't have an >> unmutilated emacs to hand to check. >> > > No, it didn't work that way without the patch: when you > mouse-set-point (mouse-1-click) in CVS emacs, the region deactivates > anyway, which _is_ normal behaviour in X11 applications come to think > of it (mouse-1-drag highlight some text in firefox, mouse-1-click > somewhere else...). Okay, I guess I read "remove mark" instead of deactivate mark. As long as C-x C-x works it is OK. Jan D. ^ permalink raw reply [flat|nested] 66+ messages in thread
* Re: Improving X selection? 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 ` (2 more replies) 0 siblings, 3 replies; 66+ messages in thread From: David De La Harpe Golden @ 2008-02-07 3:57 UTC (permalink / raw) To: rms, emacs-devel; +Cc: Horsley, Tom, Jan D. [-- Attachment #1: Type: text/plain, Size: 8820 bytes --] I'm sorry about email length (again), but if you haven't yet waded through my previous emails in this thread yet, please don't bother, just start on this one. Rev. 2 of improved X selections attempt attached (patch against recent emacs CVS HEAD). Supersedes previously sent patches and associated writeups in my previous emails in this thread. (To Tom Horsley: a part of particular interest for you re multiple selections is tagged "[TOM HORSLEY]" below.) This time, patch will (or at least should - if it doesn't, it's a bug) default to existing emacs behaviours. Sample customization that makes emacs with this patch mimic recent-X11-style interaction very closely is given at the end. Relevant customization groups: killing, mouse, editing-basics. Note again some complexity stems from trying to allow for all possible customizations of existing X11 emacs selection behaviour AND desired new behaviours. A ruthless reimplementation supporting only one recent-X11-style behaviour and/or losing backward-compat would yield rather simpler-looking code and customizations - but would hardly be acceptable for people who like all or aspects of existing emacs selection behaviour (myself included). Five files are affected in rev. 2: lisp/w32-vars.el (?!, see below) lisp/loadup.el lisp/simple.el lisp/mouse.el lisp/term/x-win.el Details of changes below - largely a more concise recap of previous mails, but sorted by file may be easier to take in as a whole. Meta: shouldn't the interprogram- functions be frame-specific somehow given multi-tty? the X11 implementations for these functions currently have an uggy check-if-frame-is-really-X. Meta: tool-bar and menu-bar cut/paste might benefit from alterations to go with these changes (but N.B. should still work as before without changes). *** 1. lisp/w32-vars.el [Niggle, but would need to be sorted somehow before any merge...] Not clear on (i) why this file is being loaded in the first place on my gnu+linux+xorg system, and (ii) not clear on what another x-select-enable-clipboard is doing in it either: presumably w32 has or should have something like w32-select-enable-clipboard for customization of its interprogram-[cut|paste]-function implementations, not screw up the x- ones. *** 2. lisp/loadup.el If I place the idle-timer based fix in simple.el, then timer needs to be loaded before it. I'm not sure this is safe, the old order might well have been that way for some reason, but seems to work. *** 3. lisp/simple.el Introduced interprogram-highlight-function analogous to interprogram-cut-function, but for outgoing highlight propagation on platforms where it makes sense (i.e. X11, mostly, though other terms could supply implementations if they wanted to provide some X11-like behaviour). The value of this function is called by the implementation of select-active-regions. Added idle-timer based implementation of select-active-regions: when region is active, have an idle timer check the active region for changes, and use interprogram-highlight-function to propagate out. Introduced interprogram-lightins-function analogous to interprogram-paste-function, but for incoming X11-style highlight/middlebutton insertions on platforms where it makes sense (i.e. X11, mostly, though other terms could supply implementations if they wanted to provide some X11-like behaviour). The value of this function is called by mouse-yank-at-click when mouse-yank-at-click-source is lightins (see mouse.el discussion below) (Note that to actually produce recent-X11-style behaviour, customizations of [the X11 implementations of] these functions and mouse behaviour, are necessary - see below mouse.el and x-win.el discussion and the example at end) *** 4. lisp/mouse.el (i) Move deactivate-mark in mouse-drag-track (mouse-1) so that it happens before initial point move. This is probably less important with the idle-timer implementation of select-active-regions (will emacs ever go idle in the middle of mouse-drag-track?), but still if the initial point move happens before the deactivate-mark, there IS a moment when the old active region has been spuriously deformed. (ii) Introduce mouse-yank-at-click-source, which allows to customize whether mouse-yank-at-click (mouse-2) gets the text to be inserted by using the kill ring yank proper (and thereby perhaps interprogram-paste-function, and perhaps adding to the kill ring), or the interprogram-lightins-function, without affecting the kill ring. (iii) Introduce mouse-save-then-kill-copy-region (mouse-3), which, analogously to mouse-drag-copy-region for mouse-drag, customizes the interaction of mouse-save-then-kill with the kill ring. original behaviour: single-click save, double-click kill new behaviour 1: just adjust active region. new behavour 2: adjust active region on single click, double-click save, triple-click kill. (point here is that active region adjustment may, depending on select-active-region, cause propagation to X11 selection(s) without affecting kill-ring via interprogram-highlight-function, whereas saving and killing will affect kill-ring and possibly also X11 selection(s) via interprogram-cut-function. So, the new behaviours are necessary to avoid confusing behaviour of mouse-3 when trying to do recent-X11-style) Should possibly also similarly augment mouse-secondary-save-then-kill. *** 5. lisp/term/x-win.el This is, perhaps despite appearances, really fairly straightforward: Supplied X11 implementations of the four (was two) interprogram-* functions in lisp/simple.el as follows: interprogram-cut => x-select-text (revised) interprogram-paste => x-cut-buffer-or-selection-value (revised) interprogram-highlight => x-select-text-for-highlight (new) interprogram-lightins => x-cut-buffer-or-selection-value-for-lightins (new) As x-select-text and x-select-text-for-highlight are nearly identical, they are both implemented as wrappers around x-select-text-for-op. These revised/new functions have an expanded range of possible customizations: Allowed specification of which of the X11 implementations of the interprogram- functions the X11 PRIMARY and CLIPBOARD selections and the legacy X Cut Buffer 0 will be involved in. I didn't bother involving X11 SECONDARY in all this. It could be done, though (mouse.el has existing secondary-handling code that is (afaik) neither hurt nor improved by this patch). This is done by allowing x-select-enable-clipboard, x-select-enable-primary and (new) x-select-enable-cutbuffer to take values other than nil and t: sets of one or more of cut, paste, highlight, lightins. nil and t also had to be supported for backward compat, and it was done "this way round" (rather than specifying for each interprogram- what selection) also for backward compat. [TOM HORSLEY] Multiple Selections: Also added something like Tom Horsley's (cc'd in case not onlist -as I'm not likely to use the feature, you might want to test if I've got the behaviour you want right!) desired feature (though different implementation to fit in with rest of changes...): As the ability for interprogram-paste-function implementations to return more than one value was added last year, add the ability for x-cut-buffer-or-selection-value to return multiple selections, customized by boolean x-cut-buffer-or-selection-value-return-multiple, and choice x-cut-buffer-or-selection-value-return-order: If -multiple is nil, then return the "winner", priority determined by -order. If -multiple is t, then return all available unique selections in order determined by -order. N.B. Existing emacs just used "winner" with a fixed order => default is existing emacs behaviour. I think the nondefault primary-first order works better with -return-multiple, FWIW. (Yes some names here are rather long. If I could slightly break transparency of the changes by e.g. removing "-cut-buffer-or" from them, they'd look much better.) *** Customization corresponding to recent-X11-style. The following, starting from an emacs -Q, makes X11 emacs + this patch closely follow recent-X11-style: kill-ring should "be" clipboard, but not primary. (though personally I prefer sort of a compromise position between this and historic emacs behaviour, but I doubt my prefs would make good default). ;; cua-mode (or pc-selection-mode) also works fine alongside ;; these settings to further "fit in". (custom-set-variables '(mouse-drag-copy-region nil) '(yank-pop-change-selection nil) '(mouse-save-then-kill-copy-region nil) '(mouse-yank-at-click-source :lightins) '(select-active-regions t) '(transient-mark-mode t) '(x-cut-buffer-or-selection-value-return-multiple nil) '(x-select-enable-clipboard (quote (:cut :paste))) '(x-select-enable-cutbuffer nil) '(x-select-enable-primary (quote (:highlight :lightins)))) [-- Warning: decoded text below may be mangled, UTF-8 assumed --] [-- Attachment #2: enhanced-x-selections_rev2.diff --] [-- Type: text/x-diff; name=enhanced-x-selections_rev2.diff, Size: 47531 bytes --] Index: lisp/w32-vars.el =================================================================== RCS file: /sources/emacs/emacs/lisp/w32-vars.el,v retrieving revision 1.19 diff -U 8 -d -r1.19 w32-vars.el --- lisp/w32-vars.el 8 Jan 2008 20:44:48 -0000 1.19 +++ lisp/w32-vars.el 7 Feb 2008 03:43:34 -0000 @@ -144,18 +144,20 @@ (repeat :inline t (choice :tag "" (const :tag "Separator" ("")) (list :tag "Font Entry" (string :tag "Menu text") (string :tag "Font"))))))) :group 'w32) -(defcustom x-select-enable-clipboard t - "*Non-nil means cutting and pasting uses the clipboard. -This is in addition to the primary selection." - :type 'boolean - :group 'killing) +;; Why is this here? For that matter, why is +;; this file being loaded in a linux/X11 build of emacs? +;;(defcustom x-select-enable-clipboard t +;; "*Non-nil means cutting and pasting uses the clipboard. +;;This is in addition to the primary selection." +;; :type 'boolean +;; :group 'killing) (provide 'w32-vars) ;;; arch-tag: ee2394fb-9db7-4c15-a8f0-66b47f4a2bb1 ;;; w32-vars.el ends here Index: lisp/loadup.el =================================================================== RCS file: /sources/emacs/emacs/lisp/loadup.el,v retrieving revision 1.160 diff -U 8 -d -r1.160 loadup.el --- lisp/loadup.el 1 Feb 2008 22:43:10 -0000 1.160 +++ lisp/loadup.el 7 Feb 2008 03:43:35 -0000 @@ -77,16 +77,17 @@ (load "button") (load "startup") (message "Lists of integers (garbage collection statistics) are normal output") (message "while building Emacs; they do not indicate a problem.") (message "%s" (garbage-collect)) (load "loaddefs.el") ;Don't get confused if someone compiled this by mistake. (message "%s" (garbage-collect)) +(load "emacs-lisp/timer") ; select-active-regions in simple.el needs timer. (load "simple") (load "help") (load "jka-cmpr-hook") ;; Any Emacs Lisp source file (*.el) loaded here after can contain ;; multilingual text. (load "international/mule-cmds") @@ -140,17 +141,16 @@ (load "jit-lock") (if (fboundp 'track-mouse) (progn (load "mouse") (and (boundp 'x-toolkit-scroll-bars) (load "scroll-bar")) (load "select"))) -(load "emacs-lisp/timer") (load "isearch") (load "rfn-eshadow") (message "%s" (garbage-collect)) (load "menu-bar") (load "paths.el") ;Don't get confused if someone compiled paths by mistake. (load "emacs-lisp/lisp") (load "textmodes/page") Index: lisp/simple.el =================================================================== RCS file: /sources/emacs/emacs/lisp/simple.el,v retrieving revision 1.899 diff -U 8 -d -r1.899 simple.el --- lisp/simple.el 1 Feb 2008 16:01:05 -0000 1.899 +++ lisp/simple.el 7 Feb 2008 03:43:41 -0000 @@ -2545,18 +2545,19 @@ (set-text-properties 0 (length string) nil string)) string))) (noprops (buffer-substring-no-properties beg end)) (t (buffer-substring beg end)))) -;;;; Window system cut and paste hooks. +;;;; Window system cut/paste and highlight/lightins hooks. +;; given multi-tty, shouldn't these be frame-local? (defvar interprogram-cut-function nil "Function to call to make a killed region available to other programs. Most window systems provide some sort of facility for cutting and pasting text between the windows of different programs. This variable holds a function that Emacs calls whenever text is put in the kill ring, to make the new kill available to other programs. @@ -2586,17 +2587,67 @@ used as the pasted text, but the other will be placed in the kill ring for easy access via `yank-pop'. Note that the function should return a string only if a program other than Emacs has provided a string for pasting; if Emacs provided the most recent string, the function should return nil. If it is difficult to tell whether Emacs or some other program provided the current string, it is probably good enough to return nil if the string -is equal (according to `string=') to the last text Emacs provided.") +is equal \(according to `string=') to the last text Emacs provided.") + +(defvar interprogram-highlight-function nil + "Function to call to make an active region available to other progams. + +In addition to clibpoard cutting and pasting \(see `interprogram-cut-function' +and `interprogram-paste-function'), at least one window system \(X11) +provides a mechanism whereby text merely highlighted in one application may + be immediately inserted into another. This variable holds a function that +`maybe-select-for-select-active-regions' calls whenever text is notionally +highlighted in emacs - i.e. there is an active region +\(see `transient-mark-mode'), and `select-active-regions'is active. + +The function takes one or two arguments, +The first argument, TEXT, is a string containing +the text that should be made available. +The second, optional, argument PUSH, has the same meaning as the +similar argument to `x-set-cut-buffer', which see.") + +(defvar interprogram-lightins-function nil + "Function to call to get text made available for lightweight +insertion from other programs. + +At least one window system (X11) provides a facility for immediately +inserting text highlighted in one program into another, bypassing +the clipboard. + +This variable holds a function that Emacs calls to obtain +text that other programs have provided for such 'lightweight +insertion'. The convention has developed on X11 +that this lightweight highlight/insertion should be entirely +independent from the clipboard proper. + +The function should be called with no arguments. If the function +returns nil, then no other program has provided such text. If the +function returns a string, then the caller of the function +\(usually `mouse-yank-at-click') will insert this string +into the buffer... without affecting the kill ring. This may +seem slightly strange, but is intended and now typical +behaviour on X11 desktops. If you DO want mouse-yank-at-click to +affect the kill ring, as it has done in the past in emacs, +adjust `mouse-yank-at-click-source' to have it use the kill +ring \(and thereby potentially `interprogram-paste-function'), which +on X11 at least \(the only relevant platform at the moment) can +in turn be adjusted to pull in PRIMARY as well as or instead of +CLIPBOARD via `x-select-enable-primary'. + +Note that the function should return a string if available +whether or not a program other than Emacs provided the string, +this is so that emacs->emacs highlight/lightins interactions +work as expected.") \f ;;;; The kill ring data structure. (defvar kill-ring nil "List of killed text sequences. Since the kill ring is supposed to interact nicely with cut-and-paste @@ -3310,54 +3361,105 @@ (marker-position (mark-marker)) (signal 'mark-inactive nil))) ;; Many places set mark-active directly, and several of them failed to also ;; run deactivate-mark-hook. This shorthand should simplify. (defsubst deactivate-mark () "Deactivate the mark by setting `mark-active' to nil. \(That makes a difference only in Transient Mark mode.) -Also runs the hook `deactivate-mark-hook'." +Also runs the hook `deactivate-mark-hook', and removes +any installed `select-active-regions' idle timer." + (and select-active-regions + (cancel-function-timers 'maybe-select-for-select-active-regions)) (cond ((eq transient-mark-mode 'lambda) (setq transient-mark-mode nil)) (transient-mark-mode (setq mark-active nil) (run-hooks 'deactivate-mark-hook)))) +(defvar select-active-regions-last-region nil + "record of last propagated region for comparison +in `maybe-select-for-select-active-regions'") + (defcustom select-active-regions nil - "If non-nil, an active region automatically becomes the window selection." + "If non-nil, an active region automatically becomes the window selection. + +Function in `interprogram-highlight-function' if any is +used to propagate the active region to the window system. +" :type 'boolean :group 'killing - :version "23.1") + :version "23.1" + :risky t + ;; make sure to deactivate idle timer on disable, in case there's + ;; a region active during the customize operation + :set (lambda (opt val) + (setq select-active-regions val) + (setq select-active-regions-last-region nil) + (if val + (progn + (cancel-function-timers 'maybe-select-for-select-active-regions) + (run-with-idle-timer 0 t + 'maybe-select-for-select-active-regions)) + (cancel-function-timers 'maybe-select-for-select-active-regions)))) + +(defun maybe-select-for-select-active-regions () + "Implements `select-active-regions'. Called by an idle timer +active when region is active and `set-mark'" + (and select-active-regions + (region-active-p) + (let ((maybe-sel-current-region-text + (buffer-substring (region-beginning) (region-end)))) + (when (or (null select-active-regions-last-region) + (not (string= select-active-regions-last-region + maybe-sel-current-region-text))) + (setq select-active-regions-last-region + maybe-sel-current-region-text) + (if (or (null maybe-sel-current-region-text) + (string= "" maybe-sel-current-region-text)) + ;; don't propagate if this region is empty, but this + ;; region being empty means future nonempty regions + ;; need repropagation + (setq select-active-regions-last-region nil) + (and interprogram-highlight-function + (funcall interprogram-highlight-function + maybe-sel-current-region-text))))))) + (defun set-mark (pos) "Set this buffer's mark to POS. Don't use this function! That is to say, don't use this function unless you want the user to see that the mark has moved, and you want the previous -mark position to be lost. +mark position to be lost. If `select-active-regions' is set, +install an idle timer to monitor the active region. Normally, when a new mark is set, the old one should go on the stack. This is why most applications should use `push-mark', not `set-mark'. Novice Emacs Lisp programmers often try to use the mark for the wrong purposes. The mark saves a location for the user's convenience. Most editing commands should not alter the mark. To remember a location for internal use in the Lisp program, store it in a Lisp variable. Example: (let ((beg (point))) (forward-line 1) (delete-region beg (point)))." (if pos (progn (setq mark-active t) (run-hooks 'activate-mark-hook) - (and select-active-regions - (x-set-selection - nil (buffer-substring (region-beginning) (region-end)))) + (when select-active-regions + (cancel-function-timers 'maybe-select-for-select-active-regions) + (run-with-idle-timer 0 t + 'maybe-select-for-select-active-regions) + ;;force immediate repropagate if mark is reset + (setq select-active-regions-last-region nil) + (maybe-select-for-select-active-regions)) (set-marker (mark-marker) pos (current-buffer))) ;; Normally we never clear mark-active except in Transient Mark mode. ;; But when we actually clear out the mark value too, ;; we must clear mark-active in any mode. (setq mark-active nil) (run-hooks 'deactivate-mark-hook) (set-marker (mark-marker) nil))) Index: lisp/mouse.el =================================================================== RCS file: /sources/emacs/emacs/lisp/mouse.el,v retrieving revision 1.326 diff -U 8 -d -r1.326 mouse.el --- lisp/mouse.el 8 Jan 2008 05:12:50 -0000 1.326 +++ lisp/mouse.el 7 Feb 2008 03:43:43 -0000 @@ -920,16 +920,21 @@ (move-overlay ol (car range) (nth 1 range)))) (defun mouse-drag-track (start-event &optional do-mouse-drag-region-post-process) "Track mouse drags by highlighting area between point and cursor. The region will be defined with mark and point, and the overlay will be deleted after return. DO-MOUSE-DRAG-REGION-POST-PROCESS should only be used by mouse-drag-region." + ;; this function defines a new region, so deactivate mark before first + ;; moving point, to avoid briefly resizing the previous active region + ;; if any. Such a brief resize can produce poor behaviour when + ;; select-active-regions is enabled. + (deactivate-mark) (mouse-minibuffer-check start-event) (setq mouse-selection-click-count-buffer (current-buffer)) (let* ((original-window (selected-window)) ;; We've recorded what we needed from the current buffer and ;; window, now let's jump to the place of the event, where things ;; are happening. (_ (mouse-set-point start-event)) (echo-keystrokes 0) @@ -966,17 +971,17 @@ (if (< (point) start-point) (goto-char start-point)) (setq start-point (point)) (if remap-double-click ;; Don't expand mouse overlay in links (setq click-count 0)) (mouse-move-drag-overlay mouse-drag-overlay start-point start-point click-count) (overlay-put mouse-drag-overlay 'window start-window) - (deactivate-mark) + ;; (deactivate-mark) (let (event end end-point last-end-point) (track-mouse (while (progn (setq event (read-event)) (or (mouse-movement-p event) (memq (car-safe event) '(switch-frame select-window)))) (if (memq (car-safe event) '(switch-frame select-window)) nil @@ -1351,30 +1356,49 @@ (mouse-minibuffer-check click) (let* ((posn (event-start click)) (click-posn (posn-point posn))) (select-window (posn-window posn)) (if (numberp click-posn) (kill-region (min (point) click-posn) (max (point) click-posn))))) +(defcustom mouse-yank-at-click-source :yank + "Source of yanked text in `mouse-yank-at-click' + +Yank: Do a full emacs kill-ring yank. Such a yank uses the emacs kill +ring and `interprogram-paste-function'. + +LightIns: Do an X11-style 'highlight/middlebutton' lightweight insert +by calling `interprogram-lightins-function', without referencing or +affecting the kill ring." + :type '(choice (const :tag "LightIns" :lightins) + (const :tag "Yank" :yank)) + :group 'mouse) + (defun mouse-yank-at-click (click arg) - "Insert the last stretch of killed text at the position clicked on. -Also move point to one end of the text thus inserted (normally the end), -and set mark at the beginning. + "Insert text from `mouse-yank-at-click-source' at the position clicked on. + +The source is either the kill-ring/clipboard or an X11-style interprogram +highlight. Also move point to one end of the text thus inserted (normally +the end), and set mark at the beginning. Prefix arguments are interpreted as with \\[yank]. If `mouse-yank-at-point' is non-nil, insert at point regardless of where you click." (interactive "e\nP") ;; 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)) - (setq this-command 'yank) (setq mouse-selection-click-count 0) - (yank arg)) + (cond ((eq mouse-yank-at-click-source :lightins) + (and interprogram-lightins-function + (insert (funcall interprogram-lightins-function)))) + (t + (setq this-command 'yank) + (yank arg)))) (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. @@ -1431,79 +1455,128 @@ ;; that came from deleting one character. (while (and tail (not (stringp (car (car tail))))) (setq tail (cdr tail))) ;; Replace it with an entry for the entire deleted text. (and tail (setcar tail (cons (car kill-ring) (min beg end)))))) (undo-boundary)) +(defcustom mouse-save-then-kill-copy-region t + "Says how many clicks needed for mouse-save-then-kill to save then kill. + +Never: only adjust active region, never kill. +Single: save on single click, kill on second click +Double: adjust active region on first click, save +on second, kill on third" + +:type '(choice (const :tag "Never" nil) + (const :tag "Single" t) + (const :tag "Double" :double)) +:group 'mouse +:version "23.1") + (defun mouse-save-then-kill (click) - "Save text to point in kill ring; the second time, kill the text. + "Depending on click count, adjust region, save to kill ring, or kill + +Behaviour customized by `mouse-save-then-kill-copy-region'. If that +is nil, clicking merely adjusts the region. If :double, single +clicking adjusts the region, double clicking saves text to kill +ring, triple clicking kills the text. If nil, single clicking saves +text to kill ring, double clicking kills. + If the text between point and the mouse is the same as what's at the front of the kill ring, this deletes the text. Otherwise, it adds the text to the kill ring, like \\[kill-ring-save], which prepares for a second click to delete the text. If you have selected words or lines, this command extends the selection through the word or line clicked on. If you do this again in a different position, it extends the selection again. -If you do this twice in the same position, the selection is killed." +" (interactive "e") (let ((before-scroll (with-current-buffer (window-buffer (posn-window (event-start click))) point-before-scroll))) (mouse-minibuffer-check click) (let ((click-posn (posn-point (event-start click))) ;; Don't let a subsequent kill command append to this one: ;; prevent setting this-command to kill-region. (this-command this-command)) (if (and (with-current-buffer (window-buffer (posn-window (event-start click))) (and (mark t) (> (mod mouse-selection-click-count 3) 0) ;; Don't be fooled by a recent click in some other buffer. (eq mouse-selection-click-count-buffer (current-buffer))))) + ;; moving by words/lines (if (not (and (eq last-command 'mouse-save-then-kill) (equal click-posn (car (cdr-safe (cdr-safe mouse-save-then-kill-posn)))))) ;; Find both ends of the object selected by this click. (let* ((range (mouse-start-end click-posn click-posn mouse-selection-click-count))) ;; Move whichever end is closer to the click. ;; That's what xterm does, and it seems reasonable. (if (< (abs (- click-posn (mark t))) (abs (- click-posn (point)))) (set-mark (car range)) (goto-char (nth 1 range))) - ;; We have already put the old region in the kill ring. - ;; Replace it with the extended region. - ;; (It would be annoying to make a separate entry.) - (kill-new (buffer-substring (point) (mark t)) t) + + (cond ((eq mouse-save-then-kill-copy-region t) ; save on first click + ;; We have already put the old region in the kill ring. + ;; Replace it with the extended region. + ;; (It would be annoying to make a separate entry.) + (kill-new (buffer-substring (point) (mark t)) t) + ;; Arrange for a repeated mouse-3 to kill this region. + (setq mouse-save-then-kill-posn + (list (car kill-ring) (point) click-posn))) + ((eq mouse-save-then-kill-copy-region :double) ; no save on first click + ;; no save on first click, but need to know region from first + ;; nil for saved kill ring top used to indicate limbo between second and third clicks + (setq mouse-save-then-kill-posn + (list nil (point) click-posn)))) (mouse-set-region-1) - ;; Arrange for a repeated mouse-3 to kill this region. - (setq mouse-save-then-kill-posn - (list (car kill-ring) (point) click-posn)) (mouse-show-mark)) - ;; If we click this button again without moving it, - ;; that time kill. - (mouse-save-then-kill-delete-region (mark) (point)) - (setq mouse-selection-click-count 0) - (setq mouse-save-then-kill-posn nil)) - (if (and (eq last-command 'mouse-save-then-kill) + (cond ((eq mouse-save-then-kill-copy-region t) ; kill on second click + ;; If we click this button again without moving it, + ;; that time kill. + (mouse-save-then-kill-delete-region (mark) (point)) + (setq mouse-selection-click-count 0) + (setq mouse-save-then-kill-posn nil)) + ((eq mouse-save-then-kill-copy-region :double) ;save on second/kill on third + (if (car-safe mouse-save-then-kill-posn) ; kill on third + (progn + (mouse-save-then-kill-delete-region (mark) (point)) + (setq mouse-selection-click-count 0) + (setq mouse-save-then-kill-posn nil)) + (progn ; save on second + (kill-new (buffer-substring (point) (mark t)) t) + (setq mouse-save-then-kill-posn + (list (car kill-ring) (point) click-posn))))))) + ;; moving by chars + (if (and (eq last-command 'mouse-save-then-kill) mouse-save-then-kill-posn - (eq (car mouse-save-then-kill-posn) (car kill-ring)) - (equal (cdr mouse-save-then-kill-posn) (list (point) click-posn))) - ;; If this is the second time we've called - ;; mouse-save-then-kill, delete the text from the buffer. - (progn - (mouse-save-then-kill-delete-region (point) (mark)) - ;; After we kill, another click counts as "the first time". - (setq mouse-save-then-kill-posn nil)) + (equal (cdr-safe mouse-save-then-kill-posn) (list (point) click-posn))) + (cond ((eq mouse-save-then-kill-copy-region t) ; kill on second click + ;; If this is the second time we've called + ;; mouse-save-then-kill, delete the text from the buffer. + (mouse-save-then-kill-delete-region (point) (mark)) + ;; After we kill, another click counts as "the first time". + (setq mouse-save-then-kill-posn nil)) + ((eq mouse-save-then-kill-copy-region :double) ; save on second / kill on third + (if (car-safe mouse-save-then-kill-posn) ; kill on third + (progn + (mouse-save-then-kill-delete-region (point) (mark)) + (setq mouse-save-then-kill-posn nil)) + (progn ; save on second + (kill-new (buffer-substring (point) (mark t)) t) + (setq mouse-save-then-kill-posn + (list (car kill-ring) (point) click-posn)))))) ;; This is not a repetition. ;; We are adjusting an old selection or creating a new one. (if (or (and (eq last-command 'mouse-save-then-kill) mouse-save-then-kill-posn) (and mark-active transient-mark-mode) (and (memq last-command '(mouse-drag-region mouse-set-region)) (or mark-even-if-inactive @@ -1515,27 +1588,36 @@ (if (numberp new) (progn ;; Move whichever end of the region is closer to the click. ;; That is what xterm does, and it seems reasonable. (if (<= (abs (- new (point))) (abs (- new (mark t)))) (goto-char new) (set-mark new)) (setq deactivate-mark nil))) - (kill-new (buffer-substring (point) (mark t)) t)) + (and (eq mouse-save-then-kill-copy-region t) ; save on first click + (kill-new (buffer-substring (point) (mark t)) t))) ;; Set the mark where point is, then move where clicked. (mouse-set-mark-fast click) (if before-scroll (goto-char before-scroll)) (exchange-point-and-mark) ;Why??? --Stef - (kill-new (buffer-substring (point) (mark t)))) - (mouse-show-mark) + (and (eq mouse-save-then-kill-copy-region t) ; save on first click + (kill-new (buffer-substring (point) (mark t))))) + (cond ((eq mouse-save-then-kill-copy-region t) ; save on first click + (setq mouse-save-then-kill-posn + (list (car kill-ring) (point) click-posn))) + ((eq mouse-save-then-kill-copy-region :double) ; no save on first click + ;; no save on first click, but need to know region from first + ;; nil for saved kill ring top used to indicate limbo between + ;;second and third clicks + (setq mouse-save-then-kill-posn + (list nil (point) click-posn)))) (mouse-set-region-1) - (setq mouse-save-then-kill-posn - (list (car kill-ring) (point) click-posn))))))) + (mouse-show-mark)))))) \f (global-set-key [M-mouse-1] 'mouse-start-secondary) (global-set-key [M-drag-mouse-1] 'mouse-set-secondary) (global-set-key [M-down-mouse-1] 'mouse-drag-secondary) (global-set-key [M-mouse-3] 'mouse-secondary-save-then-kill) (global-set-key [M-mouse-2] 'mouse-yank-secondary) (defconst mouse-secondary-overlay Index: lisp/term/x-win.el =================================================================== RCS file: /sources/emacs/emacs/lisp/term/x-win.el,v retrieving revision 1.222 diff -U 8 -d -r1.222 x-win.el --- lisp/term/x-win.el 1 Feb 2008 16:01:25 -0000 1.222 +++ lisp/term/x-win.el 7 Feb 2008 03:43:45 -0000 @@ -2135,60 +2135,180 @@ (defvar x-last-selected-text-cut nil "The value of the X cut buffer last time we selected or pasted text. The actual text stored in the X cut buffer is what encoded from this value.") (defvar x-last-selected-text-cut-encoded nil "The value of the X cut buffer last time we selected or pasted text. This is the actual text stored in the X cut buffer.") (defvar x-last-cut-buffer-coding 'iso-latin-1 "The coding we last used to encode/decode the text from the X cut buffer") +(defvar x-last-selected-return-multiple-list nil + "The last returned list from x-cut-buffer-or-selection-value when +x-cut-buffer-or-selection-value-return-multiple is on.") (defvar x-cut-buffer-max 20000 ; Note this value is overridden below. "Max number of characters to put in the cut buffer. It is said that overlarge strings are slow to put into the cut buffer.") (defcustom x-select-enable-clipboard nil - "Non-nil means cutting and pasting uses the clipboard. -This is in addition to, but in preference to, the primary selection." - :type 'boolean - :group 'killing) +"Which interprogram-cut etc. functions should use the X11 CLIPBOARD selection. + +nil : none +t : all +Or choose one or more of: +:cut : Cut (and Copy) via `x-select-text' + \(X11's `interprogram-cut-function') +:paste : Paste via `x-cut-buffer-or-selection-value' + \(X11's `interprogram-paste-function') +:highlight : Highlight via `x-select-text-for-highlight' + \(X11's `interprogram-highlight-function') +:lightins : LightIns via `x-cut-buffer-or-selection-value-for-lightins' + \(X11's `interprogram-lightins-function') + +interprogram cut and paste are associated with kill ring operations in emacs. +interprogram highlight and lightins are independent of the kill ring +and associated with `set-active-region' and `mouse-yank-at-click'" + +:type '(choice (const :tag "None" nil) + (const :tag "All" t) + (set :tag "Choose" (const :tag "Cut/Copy" :cut) + (const :tag "Paste" :paste) + (const :tag "Highlight" :highlight) + (const :tag "LightIns" :lightins))) +:group 'killing) (defcustom x-select-enable-primary t - "Non-nil means cutting and pasting uses the primary selection." - :type 'boolean - :group 'killing) +"Which interprogram-cut etc. functions should use the X11 PRIMARY selection. + +nil : none +t : all +Or choose one or more of: +:cut : Cut (and Copy) via `x-select-text' + \(X11's `interprogram-cut-function') +:paste : Paste via `x-cut-buffer-or-selection-value' + \(X11's `interprogram-paste-function') +:highlight : Highlight via `x-select-text-for-highlight' + \(X11's `interprogram-highlight-function') +:lightins : LightIns via `x-cut-buffer-or-selection-value-for-lightins' + \(X11's `interprogram-lightins-function') + +interprogram cut and paste are associated with kill ring operations in emacs. +interprogram highlight and lightins are independent of the kill ring +and associated with `set-active-region' and `mouse-yank-at-click'" + +:type '(choice (const :tag "None" nil) + (const :tag "All" t) + (set :tag "Choose" (const :tag "Cut/Copy" :cut) + (const :tag "Paste" :paste) + (const :tag "Highlight" :highlight) + (const :tag "LightIns" :lightins))) +:group 'killing) + + +(defcustom x-select-enable-cutbuffer t + "Which interprogram-cut etc. functions should use X11 legacy Cut Buffer 0. + +In X, cut buffers have long been superseded by clipboard and primary +selections. However, some old X programs use them. If you +need to exchange data between emacs and such programs via +X cut buffers, you may want to set this to a non-nil value +\(currently defaults to t to preserve historic emacs behaviour) + +nil : none +t : all +Or choose one or more of: +:cut : Cut (and Copy) via `x-select-text' + \(X11's `interprogram-cut-function') +:paste : Paste via `x-cut-buffer-or-selection-value' + \(X11's `interprogram-paste-function') +:highlight : Highlight via `x-select-text-for-highlight' + \(X11's `interprogram-highlight-function') +:lightins : LightIns via `x-cut-buffer-or-selection-value-for-lightins' + \(X11's `interprogram-lightins-function') + + +interprogram cut and paste are associated with kill ring operations in emacs. +interprogram highlight and lightins are independent of the kill ring +and associated with `set-active-region' and `mouse-yank-at-click'" + +:type '(choice (const :tag "None" nil) + (const :tag "All" t) + (set :tag "Choose" (const :tag "Cut/Copy" :cut) + (const :tag "Paste" :paste) + (const :tag "Highlight" :highlight) + (const :tag "LightIns" :lightins))) +:group 'killing +:version "23.1") + + +(defun x-select-text-for-op (op text &optional push) + "Make TEXT, a string, the primary and/or clipboard X selection. + +This function matches OP against `x-select-enable-primary' +and `x-select-enable-clipboard'. OP must be one of :cut +or :highlight, corresponding to use as an `interprogram-cut-function' +or `interprogram-highlight-function'. This function is +wrapped by `x-select-text' and `x-select-text-for-highlight' +for their use as the X11 implementations of `interprogram-cut-function' +and `interprogram-highlight-function'. + +Also may set the value of X cut buffer 0, for backward compatibility +with older X applications, matching OP against `x-select-enable-cutbuffer' -(defun x-select-text (text &optional push) - "Make TEXT, a string, the primary X selection. -Also, set the value of X cut buffer 0, for backward compatibility -with older X applications. gildea@stop.mail-abuse.org says it's not desirable to put kills in the clipboard." ;; With multi-tty, this function may be called from a tty frame. (when (eq (framep (selected-frame)) 'x) - ;; 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 + (when (or (eq x-select-enable-cutbuffer t) + (member op x-select-enable-cutbuffer)) + ;; 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 (or (eq x-select-enable-primary t) + (member op x-select-enable-primary)) (x-set-selection 'PRIMARY text) (setq x-last-selected-text-primary text)) - (when x-select-enable-clipboard + (when (or (eq x-select-enable-clipboard t) + (member op x-select-enable-clipboard)) (x-set-selection 'CLIPBOARD text) (setq x-last-selected-text-clipboard text)))) + +(defun x-select-text (text &optional push) + "Make TEXT, a string, the primary and/or clipboard X11 selection (for cut). + +Also may set the value of X cut buffer 0, for backward compatibility +with older X applications. + +This function is suitable as an `interprogram-cut-function'. +This function is implemented by calling `x-select-text-for-op' with OP :cut" + (x-select-text-for-op :cut text push)) + + +(defun x-select-text-for-highlight (text &optional push) + "Make TEXT, a string, the primary and/or clipboard X11 selection (for highlight). + +Also may set the value of X cut buffer 0, for backward compatibility +with older X applications. + +This function is suitable as an `interprogram-highlight-function'. +This function is implemented by calling `x-select-text-for-op' with OP `:highlight'" + (x-select-text-for-op :highlight text push)) + + (defvar x-select-request-type nil "*Data type request for X selection. The value is one of the following data types, a list of them, or nil: `COMPOUND_TEXT', `UTF8_STRING', `STRING', `TEXT' If the value is one of the above symbols, try only the specified type. @@ -2216,27 +2336,95 @@ (setq request-type (cdr request-type))) (condition-case nil (setq text (x-get-selection type request-type)) (error nil))) (if text (remove-text-properties 0 (length text) '(foreign-selection nil) text)) text)) -;; Return the value of the current X selection. -;; Consult the selection, and the cut buffer. Treat empty strings + +(defcustom x-cut-buffer-or-selection-value-return-multiple nil +"If non-nil `x-cut-buffer-or-selection-value' returns multiple selections. +Order is determined by `x-cut-buffer-or-selection-value-return-order'" +:type 'boolean +:group 'killing +:version "23.1") + +(defcustom x-cut-buffer-or-selection-value-return-order :cpb +"Determines precedence for return from `x-cut-buffer-or-selection-value', +the X implementation of `interprogram-paste-function'. + +Note that a selection will only actually be returned +if the associated `x-select-enable-primary' +/`x-select-enable-clipboard'/ `x-select-enable-cutbuffer' +has :paste or t set. + +If `x-cut-buffer-or-selection-value-return-multiple' is nil, +this determines precedence for the single return." + +:type '(choice + (const :tag "Clipboard > Primary > CutBuffer" :cpb) + (const :tag "Primary > Clipboard > CutBuffer" :pcb)) + ;; more could be added, but I doubt are terribly useful + ;; - Cut Buffer 0 not exactly used much. + ;; '(const :tag "Clipboard > CutBuffer > Primary" :cbp) + ;; '(const :tag "Primary > CutBuffer > Clipboard" :pbc) + ;; '(const :tag "CutBuffer > Clipboard > Primary" :bcp) + ;; '(const :tag "CutBuffer > Primary > Clipboard" :bpc) +:group 'killing +:version "23.1") + +(defcustom x-cut-buffer-or-selection-value-for-lightins-return-order :cpb +"Determines precedence for return +from `x-cut-buffer-or-selection-value-for-lightins', +the X implementation of `interprogram-paste-function'. + +Note that a selection will only actually be returned +if the associated `x-select-enable-primary' +/`x-select-enable-clipboard'/ `x-select-enable-cutbuffer' +has :lightins or t set." + +:type '(choice + (const :tag "Clipboard > Primary > CutBuffer" :cpb) + (const :tag "Primary > Clipboard > CutBuffer" :pcb)) + ;; more could be added, but I doubt are terribly useful + ;; - Cut Buffer 0 not exactly used much. + ;; '(const :tag "Clipboard > CutBuffer > Primary" :cbp) + ;; '(const :tag "Primary > CutBuffer > Clipboard" :pbc) + ;; '(const :tag "CutBuffer > Clipboard > Primary" :bcp) + ;; '(const :tag "CutBuffer > Primary > Clipboard" :bpc) +:group 'killing +:version "23.1") + + +;; Return the value(s) of the current X selection(s). +;; 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 () ;; With multi-tty, this function may be called from a tty frame. (when (eq (framep (selected-frame)) 'x) (let (clip-text primary-text cut-text) - (when x-select-enable-clipboard + + ;; Don't ever do individual newness checks when + ;; potentially returning multiple selections, + ;; in the multiple selection case, only comparing + ;; the previous entire return list produces + ;; reasonable behaviour. + (when x-cut-buffer-or-selection-value-return-multiple + (setq x-last-selected-text-primary nil + x-last-selected-text-clipboard nil + x-last-selected-text-cut nil + x-last-selected-text-cut-encoded nil)) + + (when (or (eq x-select-enable-clipboard t) + (member :paste 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 @@ -2245,17 +2433,18 @@ ((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 + (when (or (eq x-select-enable-primary t) + (member :paste 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)) @@ -2263,74 +2452,130 @@ ((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)) + (when (or (eq x-select-enable-cutbuffer t) + (member :paste x-select-enable-cutbuffer)) + (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)))))) - ;; 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)) - ;; As we have done one selection, clear this now. - (setq next-selection-coding-system nil) + ;; return one or more of the found selections. + (if x-cut-buffer-or-selection-value-return-multiple + (let ((maybe-x-sel-val-return-list + (cond ((eq :cpb x-cut-buffer-or-selection-value-return-order) + (delete-dups (delq nil (list clip-text primary-text cut-text)))) + ((eq :pcb x-cut-buffer-or-selection-value-return-order) + (delete-dups (delq nil (list primary-text clip-text cut-text))))))) + (if (or (null x-last-selected-return-multiple-list) + ;; if the return list would be same as (equal) to or + ;; equal to a head-pinned sublist of the last return, + ;; do not rereturn it. + ;; this keeps kill-ring interaction of multiple selections + ;; ... not great, but less sucky than endless duplicates. + ;; could have used clearer cl, but wanted to avoid dep. + (not (let ((a maybe-x-sel-val-return-list) + (b x-last-selected-return-multiple-list) + (sub t)) + (while (and sub + (not (null a))) + (setq sub (and (equal (car a) (car b)) + (not (null b))) + a (cdr a) + b (cdr b))) + sub))) + (setq x-last-selected-return-multiple-list + maybe-x-sel-val-return-list) + nil)) + (cond ((eq :cpb x-cut-buffer-or-selection-value-return-order) + (or clip-text primary-text cut-text)) + ((eq :pcb x-cut-buffer-or-selection-value-return-order) + (or primary-text clip-text cut-text))))))) - ;; 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) - ))) + +;; Return the value of the current X selection for a "lightweight insertion" +;; that is not intended to interact with the kill ring. No, really. +;; Consult the selection, and the cut buffer. Treat empty strings +;; as if they were unset. +;; If this function is called twice and finds the same text, +;; unlike x-cut-buffer-or-selection-value, it should return the same text. +;; See interprogram-lightins-function docstring... +(defun x-cut-buffer-or-selection-value-for-lightins () + ;; With multi-tty, this function may be called from a tty frame. + (when (eq (framep (selected-frame)) 'x) + (let (clip-text primary-text cut-text) + (when (or (eq x-select-enable-clipboard t) + (member :lightins x-select-enable-clipboard)) + (setq clip-text (x-selection-value 'CLIPBOARD)) + (if (string= clip-text "") (setq clip-text nil))) + + (when (or (eq x-select-enable-primary t) + (member :lightins x-select-enable-primary)) + (setq primary-text (x-selection-value 'PRIMARY))) + + (when (or (eq x-select-enable-cutbuffer t) + (member :lightins x-select-enable-cutbuffer)) + (setq cut-text (x-get-cut-buffer 0)) + ;; try to decode cut buffer. + (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 "")) + nil) + (t ;; 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)) + + (cond ((eq :cpb x-cut-buffer-or-selection-value-for-lightins-return-order) + (or clip-text primary-text cut-text)) + ((eq :pcb x-cut-buffer-or-selection-value-for-lightins-return-order) + (or primary-text clip-text cut-text)))))) ;; Arrange for the kill and yank functions to set and check the clipboard. (setq interprogram-cut-function 'x-select-text) (setq interprogram-paste-function 'x-cut-buffer-or-selection-value) +(setq interprogram-highlight-function 'x-select-text-for-highlight) +(setq interprogram-lightins-function 'x-cut-buffer-or-selection-value-for-lightins) (defun x-clipboard-yank () "Insert the clipboard contents, or the last stretch of killed text." (interactive "*") (let ((clipboard-text (x-selection-value 'CLIPBOARD)) (x-select-enable-clipboard t)) (if (and clipboard-text (> (length clipboard-text) 0)) (kill-new clipboard-text)) ^ permalink raw reply [flat|nested] 66+ messages in thread
* Re: Improving X selection? 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 15:14 ` Stefan Monnier 2 siblings, 1 reply; 66+ messages in thread From: Miles Bader @ 2008-02-07 4:23 UTC (permalink / raw) To: David De La Harpe Golden; +Cc: Horsley, Tom, Jan D., rms, emacs-devel "lightins"? Is this a common term? It doesn't seem to make any sense... -Miles -- People who are more than casually interested in computers should have at least some idea of what the underlying hardware is like. Otherwise the programs they write will be pretty weird. -- Donald Knuth ^ permalink raw reply [flat|nested] 66+ messages in thread
* Re: Improving X selection? 2008-02-07 4:23 ` Miles Bader @ 2008-02-07 4:59 ` David De La Harpe Golden 0 siblings, 0 replies; 66+ messages in thread From: David De La Harpe Golden @ 2008-02-07 4:59 UTC (permalink / raw) To: Miles Bader; +Cc: Horsley, Tom, Jan D., rms, emacs-devel On 07/02/2008, Miles Bader <miles.bader@necel.com> wrote: > "lightins"? > > Is this a common term? It doesn't seem to make any sense... > No, not a common term, just a contraction of "highLIGHT INSert" is all, perhaps with echo of "LIGHTweight INSert". Easy to change - suggestion? ^ permalink raw reply [flat|nested] 66+ messages in thread
* Re: Improving X selection? 2008-02-07 3:57 ` David De La Harpe Golden 2008-02-07 4:23 ` Miles Bader @ 2008-02-07 9:07 ` Jason Rumney 2008-02-07 16:32 ` David De La Harpe Golden 2008-02-07 15:14 ` Stefan Monnier 2 siblings, 1 reply; 66+ messages in thread From: Jason Rumney @ 2008-02-07 9:07 UTC (permalink / raw) To: David De La Harpe Golden; +Cc: Horsley, Tom, Jan D., rms, emacs-devel David De La Harpe Golden wrote: > *** 1. lisp/w32-vars.el > > [Niggle, but would need to be sorted somehow before any merge...] > > Not clear on (i) why this file is being loaded in the first place on > my gnu+linux+xorg system, and (ii) not clear on what another > x-select-enable-clipboard is doing in it either: presumably w32 > has or should have something like w32-select-enable-clipboard for > customization of its interprogram-[cut|paste]-function implementations, > not screw up the x- ones. > It shouldn't be loaded on non-w32 platforms, what evidence do you have that it is? The variable names are the same where the functionality is identical because lisp code that sets x-* variables should not have to do (if (eq system-type 'w32) w32-... x-...). ^ permalink raw reply [flat|nested] 66+ messages in thread
* Re: Improving X selection? 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 ` (2 more replies) 0 siblings, 3 replies; 66+ messages in thread From: David De La Harpe Golden @ 2008-02-07 16:32 UTC (permalink / raw) To: Jason Rumney; +Cc: Horsley, Tom, Jan D., rms, emacs-devel [-- Attachment #1: Type: text/plain, Size: 1209 bytes --] On 07/02/2008, Jason Rumney <jasonr@gnu.org> wrote: > It shouldn't be loaded on non-w32 platforms, what evidence do you have > that it is Just the fact that is was on my system On non-w32, e.g. add a to lisp/w32-vars.el : (defcustom this-should-not-exist-on-non-w32 t "test for w32 load issue" :type 'boolean :group 'killing) , rebuild, then emacs -Q and M-x customize-group killing => See attached screenshot, near bottom. > The variable names are the same where the functionality is identical > because lisp code that sets x-* variables should not have to do (if (eq > system-type 'w32) w32-... x-...). Not of immediate concern if I can just stop w32-vars.el being pulled in on non-w32 in the first place, but: (a) selection functionality is intrinsically not identical between w32 and x11 in the first place. (b) Code shouldn't really be setting x- variables unless it is itself x specific (I realise e.g. tool-bar might do so on even on non-x11, but it probably shouldn't, that's breaking what was a perfectly good abstraction barrier). Having w32 use what are (or were and should be) x-win customizations because some other code is x-win specific when it shouldn't be is tail wagging the dog. [-- Attachment #2: w32-vars-on-linux1.png --] [-- Type: image/png, Size: 64821 bytes --] ^ permalink raw reply [flat|nested] 66+ messages in thread
* Re: Improving X selection? 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 17:25 ` Stefan Monnier 2 siblings, 0 replies; 66+ messages in thread From: David De La Harpe Golden @ 2008-02-07 17:11 UTC (permalink / raw) To: Jason Rumney; +Cc: Horsley, Tom, Jan D., rms, emacs-devel > (b) Code shouldn't really be setting x- variables unless it is itself > x specific (I realise e.g. tool-bar might do so on even on non-x11, > but it probably shouldn't, that's breaking what was a perfectly good > abstraction barrier). (tool-bar -> menu-bar ...) ^ permalink raw reply [flat|nested] 66+ messages in thread
* Re: Improving X selection? 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-07 17:25 ` Stefan Monnier 2 siblings, 2 replies; 66+ messages in thread From: Jason Rumney @ 2008-02-07 17:13 UTC (permalink / raw) To: David De La Harpe Golden; +Cc: Horsley, Tom, Jan D., rms, emacs-devel David De La Harpe Golden wrote: > Just the fact that is was on my system > > On non-w32, e.g. add a to lisp/w32-vars.el : > (defcustom this-should-not-exist-on-non-w32 t > "test for w32 load issue" > :type 'boolean > :group 'killing) > , rebuild, then emacs -Q and M-x customize-group killing => > See attached screenshot, near bottom. > Something is messed up with cus-dep On my GNU/Linux build cus-load contains (put 'killing 'custom-loads '(w32-vars)) while on my Windows build, it contains (put 'killing 'custom-loads '(simple x-win)) Given that this variable is declared in w32-vars.el, term/x-win.el, term/mac-win.el and term/pc-win.el, I think there is a need for conditional custom-loads, or maybe we should just move that variable to a non platform-specific file. ^ permalink raw reply [flat|nested] 66+ messages in thread
* Re: Improving X selection? 2008-02-07 17:13 ` Jason Rumney @ 2008-02-07 19:46 ` Stefan Monnier 2008-02-10 18:42 ` Richard Stallman 1 sibling, 0 replies; 66+ messages in thread From: Stefan Monnier @ 2008-02-07 19:46 UTC (permalink / raw) To: Jason Rumney Cc: Horsley, Tom, David De La Harpe Golden, Jan D., rms, emacs-devel > we should just move that variable to a non > platform-specific file. Indeed. Stefan ^ permalink raw reply [flat|nested] 66+ messages in thread
* Re: Improving X selection? 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 1 sibling, 1 reply; 66+ messages in thread From: Richard Stallman @ 2008-02-10 18:42 UTC (permalink / raw) To: Jason Rumney; +Cc: Tom.Horsley, david.delaharpe.golden, jan.h.d, emacs-devel Something is messed up with cus-dep On my GNU/Linux build cus-load contains (put 'killing 'custom-loads '(w32-vars)) while on my Windows build, it contains (put 'killing 'custom-loads '(simple x-win)) I have some idea why it is doing this. The idea of cus-dep.el and cus-load.el is that if you want to look at the custom group `killing', you want to to load all the relevant files that are not loaded anyway. I think that on GNU/Linux it concludes you need to load `w32-vars', while on Losedows it thinks you need to load `x-win'. It puzzles me that it includes `simple', since that's preloaded and should therefore be excluded. I also don't know why `mac-win' does not get included. Nonetheless, it appears this is not a coding error, but a real problem of what to do in cus-dep with files meant only for one system. Since there are not a lot of such files, and we don't add new ones often, I think we don't need a very elegant solution. A simple quick solution is to define a variable in cus-dep.el that lists these files, and exclude them from consideration. Does anyone see a problem with this solution and want to do something fancier? ^ permalink raw reply [flat|nested] 66+ messages in thread
* Re: Improving X selection? 2008-02-10 18:42 ` Richard Stallman @ 2008-02-11 17:46 ` David De La Harpe Golden 0 siblings, 0 replies; 66+ messages in thread From: David De La Harpe Golden @ 2008-02-11 17:46 UTC (permalink / raw) To: rms; +Cc: Tom.Horsley, emacs-devel, jan.h.d, Jason Rumney On 10/02/2008, Richard Stallman <rms@gnu.org> wrote: > Something is messed up with cus-dep > > On my GNU/Linux build cus-load contains > > (put 'killing 'custom-loads '(w32-vars)) > > > while on my Windows build, it contains > > (put 'killing 'custom-loads '(simple x-win)) > > I have some idea why it is doing this. The idea of cus-dep.el and > cus-load.el is that if you want to look at the custom group `killing', > you want to to load all the relevant files that are not loaded anyway. > I think that on GNU/Linux it concludes you need to load `w32-vars', > while on Losedows it thinks you need to load `x-win'. > > It puzzles me that it includes `simple', since that's preloaded and > should therefore be excluded. I can't presently fully explain that (and I have no w32 to test on anyway), but note that: > I also don't know why `mac-win' does > not get included. > This is probably down to the lisp/Makefile rule custom-deps - it uses setwins_almost , which (I think) excludes contents of /term from consideration [1] - but w32-vars is not in term (maybe it should be?) Re w32: lisp/makefile.w32-in may not be doing the right thing here - (a) it uses a static WINS_ALMOST that includes term, and (b) uses WINS not WINS_ALMOST in its custom-deps anyway. [1] i.e. cd lisp ; make custom-deps EMACS=../src/emacs starts out: wd=/usr/local/src/emacs-HEAD-local/emacs/lisp; subdirs=`(cd $wd; find . -type d -print)`; for file in $subdirs; do case $file in */Old | */RCS | */CVS | */CVS/* | */.* | */.*/* | */=* | */obsolete | */term ) ;; *) wins="$wins $wd/$file" ;; esac; done; \ echo Directories: $wins; \ LC_ALL=C EMACSLOADPATH=/usr/local/src/emacs-HEAD-local/emacs/lisp LC_ALL=C ../src/emacs -batch --no-site-file --multibyte -l cus-dep --eval '(setq generated-custom-dependencies-file "/usr /local/src/emacs-HEAD-local/emacs/lisp/cus-load.el")' -f custom-make-dependencies $wins Directories: /usr/local/src/emacs-HEAD-local/emacs/lisp/. /usr/local/src/emacs-HEAD-local/emacs/lisp/./language /usr/local/src/emacs-HEAD-local/emacs/lisp/./net /usr/local/src/emacs-HEAD-local/em acs/lisp/./nxml /usr/local/src/emacs-HEAD-local/emacs/lisp/./calendar /usr/local/src/emacs-HEAD-local/emacs/lisp/./international /usr/local/src/emacs-HEAD-local/emacs/lisp/./emulation /usr/local/ src/emacs-HEAD-local/emacs/lisp/./textmodes /usr/local/src/emacs-HEAD-local/emacs/lisp/./eshell /usr/local/src/emacs-HEAD-local/emacs/lisp/./url /usr/local/src/emacs-HEAD-local/emacs/lisp/./play /usr/local/src/emacs-HEAD-local/emacs/lisp/./progmodes /usr/local/src/emacs-HEAD-local/emacs/lisp/./emacs-lisp /usr/local/src/emacs-HEAD-local/emacs/lisp/./mh-e /usr/local/src/emacs-HEAD-local/emacs/lisp/./mail /usr/local/src/emacs-HEAD-local/emacs/lisp/./erc /usr/local/src/emacs-HEAD-local/emacs/lisp/./gnus /usr/local/src/emacs-HEAD-local/emacs/lisp/./calc Directory /usr/local/src/emacs-HEAD-local/emacs/lisp/. ^ permalink raw reply [flat|nested] 66+ messages in thread
* Re: Improving X selection? 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 17:25 ` Stefan Monnier 2008-02-07 17:39 ` David De La Harpe Golden 2 siblings, 1 reply; 66+ messages in thread From: Stefan Monnier @ 2008-02-07 17:25 UTC (permalink / raw) To: David De La Harpe Golden Cc: Horsley, Tom, Jan D., emacs-devel, rms, Jason Rumney > On non-w32, e.g. add a to lisp/w32-vars.el : > (defcustom this-should-not-exist-on-non-w32 t > "test for w32 load issue" > :type 'boolean > :group 'killing) A better test is to add (message "we're loading w32-vars") or (error "we're loading w32-vars") or (debug) > , rebuild, then emacs -Q and M-x customize-group killing => > See attached screenshot, near bottom. It's quite likely that w32-vars gets loaded by the call to M-x customize-group (via cus-load.el). So the solution to the original problem is to move the x-select-* defcustom outside of platform-specific files so that there's only one copy of it. Stefan ^ permalink raw reply [flat|nested] 66+ messages in thread
* Re: Improving X selection? 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 0 siblings, 2 replies; 66+ messages in thread From: David De La Harpe Golden @ 2008-02-07 17:39 UTC (permalink / raw) To: Stefan Monnier; +Cc: Horsley, Tom, Jan D., emacs-devel, rms, Jason Rumney On 07/02/2008, Stefan Monnier <monnier@iro.umontreal.ca> wrote: > It's quite likely that w32-vars gets loaded by the call to M-x > customize-group (via cus-load.el). So the solution to the original > problem is to move the x-select-* defcustom outside of platform-specific > files so that there's only one copy of it. > That would forever entrench its usage as a non-platform-specific customisation, which is IMO not good design, and then would mean yet another customization needs to be introduced to actually customize the x specifics! Adjustment/fix of cus-load as suggested in Jason R.'s mail is a better interim solution, allowing eventual fixup: The platforms in term/ supply their own interprogram-cut/paste-functions - at least mac-win and pc-win and x-win do - though they name-clashing name them x-select-text - IMO should be e.g. mac-select-text on mac. IMO the purpose of x-select-enable-clipboard should be to configure the behaviour of the _x-_ implementation of the interprogram-cut/paste-functions, there should be mac-select-text for the mac interprogram-cut-function customized by mac-select-enable-clipboard etc. I suspect this is mostly just a result of cut-n-paste-coding from x-win to the other term/ implementations, and slightly tail-wagging-dog menu-bar.el compat. ^ permalink raw reply [flat|nested] 66+ messages in thread
* Re: Improving X selection? 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 1 sibling, 0 replies; 66+ messages in thread From: David De La Harpe Golden @ 2008-02-07 17:51 UTC (permalink / raw) To: Stefan Monnier; +Cc: Horsley, Tom, Jan D., emacs-devel, rms, Jason Rumney [-- Attachment #1: Type: text/plain, Size: 27 bytes --] Just an e.g. for pc-win... [-- Warning: decoded text below may be mangled, UTF-8 assumed --] [-- Attachment #2: eg-pc-win-interprogram-change.diff --] [-- Type: text/x-diff; name=eg-pc-win-interprogram-change.diff, Size: 2735 bytes --] Index: pc-win.el =================================================================== RCS file: /sources/emacs/emacs/lisp/term/pc-win.el,v retrieving revision 1.45 diff -U 8 -d -r1.45 pc-win.el --- pc-win.el 8 Jan 2008 20:45:45 -0000 1.45 +++ pc-win.el 7 Feb 2008 17:48:45 -0000 @@ -171,54 +171,54 @@ ;; From lisp/term/w32-win.el ; ;;;; Selections and cut buffers ; ;;; We keep track of the last text selected here, so we can check the ;;; current selection against it, and avoid passing back our own text ;;; from x-cut-buffer-or-selection-value. -(defvar x-last-selected-text nil) +(defvar msdos-last-selected-text nil) -(defcustom x-select-enable-clipboard t +(defcustom msdos-select-enable-clipboard t "Non-nil means cutting and pasting uses the clipboard. This is the default on this system, since MS-Windows does not support other types of selections." :type 'boolean :group 'killing) -(defun x-select-text (text &optional push) - (if x-select-enable-clipboard +(defun msdos-select-text (text &optional push) + (if msdos-select-enable-clipboard (w16-set-clipboard-data text)) - (setq x-last-selected-text text)) + (setq msdos-last-selected-text text)) ;;; Return the value of the current selection. ;;; Consult the selection, then the cut buffer. Treat empty strings ;;; as if they were unset. -(defun x-get-selection-value () - (if x-select-enable-clipboard +(defun msdos-get-selection-value () + (if msdos-select-enable-clipboard (let (text) ;; Don't die if x-get-selection signals an error. (condition-case c (setq text (w16-get-clipboard-data)) (error (message "w16-get-clipboard-data:%s" c))) (if (string= text "") (setq text nil)) (cond ((not text) nil) - ((eq text x-last-selected-text) nil) - ((string= text x-last-selected-text) + ((eq text msdos-last-selected-text) nil) + ((string= text msdos-last-selected-text) ;; Record the newer string, so subsequent calls can use the 'eq' test. - (setq x-last-selected-text text) + (setq msdos-last-selected-text text) nil) (t - (setq x-last-selected-text text)))))) + (setq msdos-last-selected-text text)))))) ;;; Arrange for the kill and yank functions to set and check the clipboard. -(setq interprogram-cut-function 'x-select-text) -(setq interprogram-paste-function 'x-get-selection-value) +(setq interprogram-cut-function 'msdos-select-text) +(setq interprogram-paste-function 'msdos-get-selection-value) ;; From lisp/faces.el: we only have one font, so always return ;; it, no matter which variety they've asked for. (defun x-frob-font-slant (font which) font) (make-obsolete 'x-frob-font-slant 'make-face-... "21.1") (defun x-frob-font-weight (font which) font) ^ permalink raw reply [flat|nested] 66+ messages in thread
* Re: Improving X selection? 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 1 sibling, 0 replies; 66+ messages in thread From: Stefan Monnier @ 2008-02-07 19:54 UTC (permalink / raw) To: David De La Harpe Golden Cc: Horsley, Tom, Jan D., emacs-devel, rms, Jason Rumney > That would forever entrench its usage as a non-platform-specific > customisation, Which is good. > which is IMO not good design, and then would mean yet another > customization needs to be introduced to actually customize the > x specifics! I don't see why we'd need anything else specific for X. If it's not sufficient for X (or for w32 or ...), then we can add yet more generic config vars, and then either ignore them on other GUIs or interpret them as best as we can. > The platforms in term/ supply their own > interprogram-cut/paste-functions - at least mac-win and pc-win and > x-win do - though they name-clashing name them x-select-text - IMO > should be e.g. mac-select-text on mac. As long as the C code can only be built with 1 GUI at the same time, this is not a big issue, but yes, that's of course true. > IMO the purpose of x-select-enable-clipboard should be to configure > the behaviour of the _x-_ implementation of the > interprogram-cut/paste-functions, Of course, it should be renamed to `select-enable-clipboard'. Stefan ^ permalink raw reply [flat|nested] 66+ messages in thread
* Re: Improving X selection? 2008-02-07 3:57 ` David De La Harpe Golden 2008-02-07 4:23 ` Miles Bader 2008-02-07 9:07 ` Jason Rumney @ 2008-02-07 15:14 ` Stefan Monnier 2008-02-07 16:15 ` David De La Harpe Golden 2 siblings, 1 reply; 66+ messages in thread From: Stefan Monnier @ 2008-02-07 15:14 UTC (permalink / raw) To: David De La Harpe Golden; +Cc: Horsley, Tom, Jan D., rms, emacs-devel Could you remind us what is the UI-behaviors that you want to provide that requires interprogram-highlight-function (and same thing for interprogram-lightins-function)? Stefan ^ permalink raw reply [flat|nested] 66+ messages in thread
* Re: Improving X selection? 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 0 siblings, 1 reply; 66+ messages in thread From: David De La Harpe Golden @ 2008-02-07 16:15 UTC (permalink / raw) To: Stefan Monnier; +Cc: Horsley, Tom, Jan D., rms, emacs-devel On 07/02/2008, Stefan Monnier <monnier@iro.umontreal.ca> wrote: > Could you remind us what is the UI-behaviors that you want to provide > that requires interprogram-highlight-function (and same thing for > interprogram-lightins-function)? > N.B. I used interprogram-*-functions rather than X11isms (considered mouse-yank-primary to be an X11ism) to preserve valuable abstraction barriers between term (window system) specifics and emacs core. Such barriers are perhaps currently crumbled slightly as Jason Rumney's recent w32-vars mail in this thread illustrates, but are IMO worthy of repair, not teardown, especially given multi-tty. Highlight: recent-X11-style behaviour, propagate the active region to the X11 primary, _without_ affecting clipboard or kill-ring. lightins: recent-X11-style behaviour, middle-button insert of X11 primary, _without_ affecting clipboard or kill-ring. ^ permalink raw reply [flat|nested] 66+ messages in thread
* Re: Improving X selection? 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 ` (2 more replies) 0 siblings, 3 replies; 66+ messages in thread From: Stephen J. Turnbull @ 2008-02-07 18:01 UTC (permalink / raw) To: David De La Harpe Golden Cc: Horsley, Tom, Jan D., emacs-devel, Stefan Monnier, rms David De La Harpe Golden writes: > Highlight: > > recent-X11-style behaviour, propagate the active region to the X11 primary, > _without_ affecting clipboard or kill-ring. Er, if "recent ... behavior" is the rationale for "propagate ... kill-ring", your time-scale is geological. The current behavior of Emacs (and XEmacs) was generally decided ages ago, deliberately flouting the conventions of X11 (I believe these are recommended but not mandated by the ICCCM), which haven't changed since then AFAICT. My understanding is that this behavior was hotly debated at that time, and deliberately chosen. I see no reason why users should not get the behavior you've implemented if they want it (I think it better corresponds to my personal preferences, for one thing ;-), but (1) The defaults should not change without substantial experimentation. (I believe you've taken care about that already, but it deserves emphasis.) (2) I expect it will be important to uptake that any behavior be substantially mimicked on non-X platforms if at all possible. The (admittedly approximate) constancy of semantics of mouse gestures across platforms is something that many of our users find very important (and we're talking a decade of experience in XEmacs, dunno how long Emacs has been usable on Windows or if Emacs has many users who swing both ways ... I know the maintainer doesn't!). > lightins: Yuck. Sounds like occupying a government office as a demonstration against opaque politics. Please spell out your intended expansion, and let the users choose the abbreviation. > recent-X11-style behaviour, middle-button insert of X11 primary, > _without_ affecting clipboard or kill-ring. How does middle-button *affect* clipboard and/or kill-ring? Do you mean something like "consult"? ^ permalink raw reply [flat|nested] 66+ messages in thread
* Re: Improving X selection? 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-07 18:22 ` David De La Harpe Golden [not found] ` <8e24944a0802071042u43d68f04pc8492ad8ce07aa18@mail.gmail.com> 2 siblings, 1 reply; 66+ messages in thread From: David De La Harpe Golden @ 2008-02-07 18:07 UTC (permalink / raw) To: Stephen J. Turnbull Cc: Horsley, Tom, Jan D., emacs-devel, Stefan Monnier, rms On 07/02/2008, Stephen J. Turnbull <stephen@xemacs.org> wrote: > How does middle-button *affect* clipboard and/or kill-ring? Do you > mean something like "consult"? > Consult clipboard, affect kill ring. With existing emacs unpatched mouse-yank-at-click, the kill-ring is affected (since the yank uses current-kill which uses the interprogram-paste-function, potentially /pushing onto/ kill ring.) As I realised some users probably like middle-button inserted text being subsequently available on the kill ring (it is after all current emacs behaviour!), I allowed two ways for mouse-yank-at-click to work. If mouse-yank-at-click-source is yank, then a kill-ring yank (and thereby current-kill and interprogram-paste-function) is used, and if it is lightins, then the interpgroam-lightins-function is used and the kill ring is not touched. With the extended x-select-enable-clipboard and x-select-enable-primary, it is possible to specify whether clipboard or primary or both should be pulled in with (the X11 implementations of) interprogram-paste-function or interprogram-lightins-function. This allows both all historic emacs customizations and intended behaviour. ^ permalink raw reply [flat|nested] 66+ messages in thread
* Re: Improving X selection? 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 0 siblings, 1 reply; 66+ messages in thread From: Stephen J. Turnbull @ 2008-02-07 19:21 UTC (permalink / raw) To: David De La Harpe Golden Cc: Horsley, Tom, Jan D., Stefan Monnier, rms, emacs-devel David De La Harpe Golden writes: > On 07/02/2008, Stephen J. Turnbull <stephen@xemacs.org> wrote: > > > How does middle-button *affect* clipboard and/or kill-ring? Do you > > mean something like "consult"? > > > Consult clipboard, affect kill ring. With existing emacs unpatched > mouse-yank-at-click, the kill-ring is affected (since the yank uses > current-kill which uses the interprogram-paste-function, potentially > /pushing onto/ kill ring.) Oh, right. If you change primary selection semantics from current Emacs semantics to standard X11 semantics, then only by accident will the current selection already be on the kill-ring. This reveals a side effect of current Emacs "paste selection" implementation. Have you given thought to queueing (ie, at the back of the kill-ring) the primary selection rather than pushing it (on the front)? Seems an obvious "best of both worlds combination" of current Emacs behavior and purist X11 semantics. I guess it's a YAGNI, and pollutes the kill-ring in this context? ^ permalink raw reply [flat|nested] 66+ messages in thread
* Re: Improving X selection? 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 0 siblings, 1 reply; 66+ messages in thread From: Miles Bader @ 2008-02-08 1:19 UTC (permalink / raw) To: Stephen J. Turnbull Cc: Horsley, Tom, rms, David De La Harpe Golden, emacs-devel, Stefan Monnier, Jan D. "Stephen J. Turnbull" <stephen@xemacs.org> writes: > Have you given thought to queueing (ie, at the back of the kill-ring) > the primary selection rather than pushing it (on the front)? Seems an > obvious "best of both worlds combination" of current Emacs behavior > and purist X11 semantics. I'm not sure I understand what you mean. What I (and many others) like about the current implementation is that you can do "Select" in say, xterm, and then do "C-y" in Emacs to yank that selection. It sounds like your idea would instead make the current selection available via "C-y M-y" which sounds maddeningly unintuitive -- the current selection, after all, is _current_... -Miles -- Patience, n. A minor form of despair, disguised as a virtue. ^ permalink raw reply [flat|nested] 66+ messages in thread
* Re: Improving X selection? 2008-02-08 1:19 ` Miles Bader @ 2008-02-08 1:42 ` David De La Harpe Golden 0 siblings, 0 replies; 66+ messages in thread From: David De La Harpe Golden @ 2008-02-08 1:42 UTC (permalink / raw) To: Miles Bader Cc: Horsley, Tom, rms, emacs-devel, Stefan Monnier, Stephen J. Turnbull, Jan D. On 08/02/2008, Miles Bader <miles@gnu.org> wrote: > It sounds like your idea would instead make the current selection > available via "C-y M-y" which sounds maddeningly unintuitive -- the > current selection, after all, is _current_... > Well, then please, try the fish, I mean the rev 2 patch, with a (customization group killing): x-cut-buffer-or-selection-value-return-multiple t x-cut-buffer-or-selection-value-return-order :pcb x-select-enable-clipboard including :paste in its choose list (or t) x-select-enable-primary also including :paste in its choose list (or t) - then, when you C-y, the primary X11 selection (i.e. currently highlighted) thing is inserted (and put on the kill ring), and the clipboard, if any was found, and if different, is an M-y away. This is a variant the "Tom Horsley thang", which the patch IMO supports nicely even though I don't like it much myself. ^ permalink raw reply [flat|nested] 66+ messages in thread
* Re: Improving X selection? 2008-02-07 18:01 ` Stephen J. Turnbull 2008-02-07 18:07 ` David De La Harpe Golden @ 2008-02-07 18:22 ` David De La Harpe Golden 2008-02-07 19:45 ` Stefan Monnier [not found] ` <8e24944a0802071042u43d68f04pc8492ad8ce07aa18@mail.gmail.com> 2 siblings, 1 reply; 66+ messages in thread From: David De La Harpe Golden @ 2008-02-07 18:22 UTC (permalink / raw) To: Stephen J. Turnbull Cc: Horsley, Tom, Jan D., emacs-devel, Stefan Monnier, rms On 07/02/2008, Stephen J. Turnbull <stephen@xemacs.org> wrote: > The current behavior > of Emacs (and XEmacs) was generally decided ages ago, deliberately > flouting the conventions of X11 (I believe these are recommended but > not mandated by the ICCCM), which haven't changed since then AFAICT. > My understanding is that this behavior was hotly debated at that time, > and deliberately chosen. Since then, freedesktop.org has further spoken, so things have in fact changed slightly: http://standards.freedesktop.org/clipboards-spec/clipboards-latest.txt > > lightins: > > Yuck. Sounds like occupying a government office as a demonstration > against opaque politics. Please spell out your intended expansion, > and let the users choose the abbreviation. > Would be nice to find one that didn't induce an extra hyphen is all - interprogram-cut-function interprogram-paste-function interprogram-highlight-function interprogram-highlight-insert-function is just annoyingly asymmetric looking. It's probably "good enough" though, unless there's a better suggestion. ^ permalink raw reply [flat|nested] 66+ messages in thread
* Re: Improving X selection? 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:01 ` Tom Horsley 0 siblings, 2 replies; 66+ messages in thread From: Stefan Monnier @ 2008-02-07 19:45 UTC (permalink / raw) To: David De La Harpe Golden Cc: Horsley, Tom, Stephen J. Turnbull, Jan D., rms, emacs-devel > Would be nice to find one that didn't induce an extra hyphen is all - > interprogram-cut-function > interprogram-paste-function > interprogram-highlight-function > interprogram-highlight-insert-function The name "interprogram-highlight-function" sounds wrong: the user does not highlight the text, she selects it (the highlighting is done by the application to help the user figure out what is selected). So I suggest `interprogram-select-function' for it. For the last one, I suggest we use `interprogram-insert-function', tho I'm not completely sure I understand what it's intended to do. The following is some random analysis of the situation, for my own good. From what I can tell, there are 4 kinds of selections: - C-SPC + mouse movement. I.e. select-only. - same plus C-w. - selection with the mouse. - one of the above plus "copy" from the menu. No 4 should always use the CLIPBOARD. No 3 should always use the PRIMARY (plus optionally CLIPBOARD) No 2 may optionally use PRIMARY (plus optionally CLIPBOARD) No 1 should use neither or at most PRIMARY. I believe that currently No 2 and No 3 are always handled in the same way, and I don't know if we want to bother separating them. I also believe that the use of CLIPBOARD for 2 and 3 depends on x-select-enable-clipboard. You're suggesting to allow PRIMARY for No 1 via `select-active-regions'? Oh, I see it already exists, so you're just trying to fix it so it works more reliably, is that right? Why do you need `interprogram-highlight-function'? Can't you just use (let ((x-select-enable-clipboard nil)) (kill-ring-save beg end)) like clipboard-kill-ring-save does? On the lighins side, I understand even less why there's a need for interprogram-highlight-insert-function. We have 3 different situations: - C-y - mouse-2 - "Paste" from the menu For all three cases, the first question is "where does the text come from": No 3 should always use the CLIPBOARD then PRIMARY then kill ring. No 2 should use the CLIPBOARD only if x-select-enable-clipboard is set. No 1 is identical except it may also not check PRIMARY either. In all 3 cases a further question is: if the yanked text comes from the CLIPBOARD or the PRIMARY, should the text be added to the kill-ring? This last question is the one you seem to want to address, but I don't see why you need interprogram-highlight-insert-function for it, instead of just a boolean config var. And to be honest: I doubt that there's enough of a need for this level of control to justify its introduction; it's easy enough to use M-y to get back to the previous item. This said, if we introduce such a "copy-interprogram-text-to-kill-ring" config var, we could give it 3 values: either the kill-ring is never affected, or the kill-ring is filled from CLIPBOARD/PRIMARY upon yank, or the kill-ring is not only filled upon yank but also upon kill (that's a patch I suggested a few months back: before pushing something to the CLIPBOARD/PRIMARY, check the previous value, and if it's not ours, stash it in kill-ring, thus integrating the kill-ring with the PRIMARY/CLIPBOARD even more tightly). Stefan ^ permalink raw reply [flat|nested] 66+ messages in thread
* Re: Improving X selection? 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 22:43 ` Stefan Monnier 2008-02-07 21:01 ` Tom Horsley 1 sibling, 2 replies; 66+ messages in thread From: David De La Harpe Golden @ 2008-02-07 20:39 UTC (permalink / raw) To: Stefan Monnier Cc: Horsley, Tom, Stephen J. Turnbull, Jan D., rms, emacs-devel On 07/02/2008, Stefan Monnier <monnier@iro.umontreal.ca> wrote: > The name "interprogram-highlight-function" sounds wrong: the user does > not highlight the text, she selects it (the highlighting is done by the > application to help the user figure out what is selected). So I suggest > `interprogram-select-function' for it. I thought of that, but wanted to avoid "select" because of its X11 usage: that which is cut is also a selection in X11 terms. Still, it's not terrible, and fits in with select-active-regions. N.B. interprogram-highlight-function is used only when select-active-regions is active. > For the last one, I suggest we > use `interprogram-insert-function', tho I'm not completely sure > I understand what it's intended to do. It is intended to be for inserting texts retrieved from the window system which are to be inserted without side-effecting the kill ring. It is only used in the very specific case of (the patched) mouse-yank-at-click with mouse-yank-at-click set to lightins rather than yank. Remember, the goal is allow a configuration where primary /never makes its way into the kill ring/, while still allowing its insertion with middle-click. If you're a long-time emacs user used to (or given the audience, partially responsible for!) existing behaviour, you're probably now wondering why the heck you want that - fortunately for you, patch defaults to existing behaviour. > From what I can tell, there are 4 kinds of selections: > - C-SPC + mouse movement. I.e. select-only. > - same plus C-w. > - selection with the mouse. > - one of the above plus "copy" from the menu. > > No 4 should always use the CLIPBOARD. > No 3 should always use the PRIMARY (plus optionally CLIPBOARD) > No 2 may optionally use PRIMARY (plus optionally CLIPBOARD) > No 1 should use neither or at most PRIMARY. > > I believe that currently No 2 and No 3 are always handled in the same > way, and I don't know if we want to bother separating them. I'm not 100% sure what you meant by "selection with mouse" there : No 1 covers "selection [only] with mouse". > I also believe that the use of CLIPBOARD for 2 and 3 depends on > x-select-enable-clipboard. Yes. > You're suggesting to allow PRIMARY for No 1 via `select-active-regions'? > Oh, I see it already exists, so you're just trying to fix it so it > works more reliably, is that right? > Yes (and making it not x-specific.). > Why do you need `interprogram-highlight-function'? Can't you just use > > (let ((x-select-enable-clipboard nil)) > (kill-ring-save beg end)) > > like clipboard-kill-ring-save does? > No, that would affect the kill ring! If mouse-drag-copy-region is on (the default), then mouse-selecting uses the the kill ring and side-effects the X11 selection via interprogram-cut-function, so select-active-regions is not necessary. But if mouse-drag-copy-region is off (so mouse-selecting doesn't affect the kill ring, only mouse-selecting then killing...), then select-active-regions is necessary (for mouse AND keyboard) to propagate out to primary. > On the lighins side, I understand even less why there's a need for > interprogram-highlight-insert-function. We have 3 different situations: > - C-y > - mouse-2 > - "Paste" from the menu > > For all three cases, the first question is "where does the text come from": > No 3 should always use the CLIPBOARD then PRIMARY then kill ring. [I'd say it should always use CLIPBOARD then kill ring, never PRIMARY, it should just do a yank, which via current-kill may pull in CLIPBOARD) > No 2 should use the CLIPBOARD only if x-select-enable-clipboard is set. ... but *not* add to kill ring! (unless the user wants it to) No 1 IS a yank, (which via current-kill/interprogram-paste-function) may pull in CLIPBOARD. > thus integrating the kill-ring with the > PRIMARY/CLIPBOARD even more tightly). Hmm. May have to think through your last part more, but just to stress, my goal is to allow at least one point in the customization space that: 1. totally separates x11 primary and the kill-ring, 2. unifies x11 clipboard and kill-ring. 3 while still allowing get (by middlebutton-insert) and set (by keyboard or mouse selection leading to highlight) of primary. ^ permalink raw reply [flat|nested] 66+ messages in thread
* Re: Improving X selection? 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-07 22:43 ` Stefan Monnier 1 sibling, 1 reply; 66+ messages in thread From: Stephen J. Turnbull @ 2008-02-07 21:25 UTC (permalink / raw) To: David De La Harpe Golden Cc: Horsley, Tom, Jan D., emacs-devel, Stefan Monnier, rms David De La Harpe Golden writes: > I thought of that, but wanted to avoid "select" because of its X11 > usage: that which is cut is also a selection in X11 terms. Well, yes, you can't cut without selection, but I've never heard "select" used to mean "cut". A selection is just a region of a window, which can be deleted, cut, copied (with or without translation) or replaced as a single unit. +1 for "select" rather than "highlight", and for "insert" as opposed to "lightins". ^ permalink raw reply [flat|nested] 66+ messages in thread
* Re: Improving X selection? 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 0 siblings, 1 reply; 66+ messages in thread From: David De La Harpe Golden @ 2008-02-07 21:41 UTC (permalink / raw) To: Stephen J. Turnbull Cc: Horsley, Tom, Jan D., emacs-devel, Stefan Monnier, rms On 07/02/2008, Stephen J. Turnbull <stephen@xemacs.org> wrote: > David De La Harpe Golden writes: > > > I thought of that, but wanted to avoid "select" because of its X11 > > usage: that which is cut is also a selection in X11 terms. > > Well, yes, you can't cut without selection, but I've never heard > "select" used to mean "cut". A selection is just a region of a > window, which can be deleted, cut, copied (with or without > translation) or replaced as a single unit. > > +1 for "select" rather than "highlight", and for "insert" as opposed > to "lightins". > Okay, but then you have to be very careful about what x-select-enable-clipboard (or even a "select-enable-clipboard") actually denotes IMO: By that reading, a logical interpretation of a boolean var called select-enable-clipboard might be that when t, when text is merely selected, the clipboard is to be affected, and not the current meaning (that is: whether the X11 CLIPBOARD selection should be affected or consulted in various kill/yank/select operations!). Thus, this patch's x-select-enable-clipboard if named for clarity rather than backward-compatibility would be called something like "enable-clipboard-for", taking a list of one or more of :cut, :paste, :select and :insert. (or kill, yank, select and insert) ^ permalink raw reply [flat|nested] 66+ messages in thread
* Re: Improving X selection? 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 0 siblings, 1 reply; 66+ messages in thread From: Stephen J. Turnbull @ 2008-02-08 0:22 UTC (permalink / raw) To: David De La Harpe Golden Cc: Horsley, Tom, Jan D., Stefan Monnier, rms, emacs-devel David De La Harpe Golden writes: > Okay, but then you have to be very careful about what > x-select-enable-clipboard (or even a "select-enable-clipboard") > actually denotes IMO: > > By that reading, a logical interpretation of a boolean var called > select-enable-clipboard might be that when t, when text is merely > selected, the clipboard is to be affected, You mean that text would actually be copied to the clipboard? YMMV, but it would never occur to me to interpret it that way. Rather, I would interpret it that when text is selected, the til-then snoozing clipboard gets a light tap on its shoulder "hey, man, wake up, we may have some work for you to do!" (and then again, we may not). ^ permalink raw reply [flat|nested] 66+ messages in thread
* Re: Improving X selection? 2008-02-08 0:22 ` Stephen J. Turnbull @ 2008-02-08 1:26 ` David De La Harpe Golden 0 siblings, 0 replies; 66+ messages in thread From: David De La Harpe Golden @ 2008-02-08 1:26 UTC (permalink / raw) To: Stephen J. Turnbull Cc: Horsley, Tom, Jan D., Stefan Monnier, rms, emacs-devel On 08/02/2008, Stephen J. Turnbull <stephen@xemacs.org> wrote: > David De La Harpe Golden writes: > > > Okay, but then you have to be very careful about what > > x-select-enable-clipboard (or even a "select-enable-clipboard") > > actually denotes IMO: > > > > By that reading, a logical interpretation of a boolean var called > > select-enable-clipboard might be that when t, when text is merely > > selected, the clipboard is to be affected, > > You mean that text would actually be copied to the clipboard? YMMV, > but it would never occur to me to interpret it that way. But that IS one of several effects of x-select-enable-clipboard t with mouse-drag-copy-region t in existing emacs when you merely select text with a mouse drag (but only because mouse-drag-track with mouse-drag-copy-region t does a copy-region-as-kill, which does an interprogram-cut-function, which affects the clipboard if x-select-enable-clipboard is t) ^ permalink raw reply [flat|nested] 66+ messages in thread
* Re: Improving X selection? 2008-02-07 20:39 ` David De La Harpe Golden 2008-02-07 21:25 ` Stephen J. Turnbull @ 2008-02-07 22:43 ` Stefan Monnier 2008-02-08 2:50 ` David De La Harpe Golden 1 sibling, 1 reply; 66+ messages in thread From: Stefan Monnier @ 2008-02-07 22:43 UTC (permalink / raw) To: David De La Harpe Golden Cc: Horsley, Tom, Stephen J. Turnbull, Jan D., rms, emacs-devel >> For the last one, I suggest we >> use `interprogram-insert-function', tho I'm not completely sure >> I understand what it's intended to do. > It is intended to be for inserting texts retrieved from the window > system which are to be inserted without side-effecting the kill ring. > It is only used in the very specific case of (the patched) > mouse-yank-at-click with mouse-yank-at-click set to lightins rather > than yank. I understand thatm but I don't see a need for a separate interprogram-insert-function. I only see the need for some more boolean custom vars. >> From what I can tell, there are 4 kinds of selections: >> - C-SPC + mouse movement. I.e. select-only. ^^^^^ cursor Duh! >> - same plus C-w. >> - selection with the mouse. >> - one of the above plus "copy" from the menu. >> >> No 4 should always use the CLIPBOARD. >> No 3 should always use the PRIMARY (plus optionally CLIPBOARD) >> No 2 may optionally use PRIMARY (plus optionally CLIPBOARD) >> No 1 should use neither or at most PRIMARY. >> >> I believe that currently No 2 and No 3 are always handled in the same >> way, and I don't know if we want to bother separating them. > I'm not 100% sure what you meant by "selection with mouse" there : > No 1 covers "selection [only] with mouse". Yes, sorry, the "mouse movement" above was a typo. >> You're suggesting to allow PRIMARY for No 1 via `select-active-regions'? >> Oh, I see it already exists, so you're just trying to fix it so it >> works more reliably, is that right? > Yes (and making it not x-specific.). Yes, that's good. >> Why do you need `interprogram-highlight-function'? Can't you just use >> >> (let ((x-select-enable-clipboard nil)) >> (kill-ring-save beg end)) >> >> like clipboard-kill-ring-save does? > No, that would affect the kill ring! Then add x-select-enable-kill-ring. Big deal. >> No 2 should use the CLIPBOARD only if x-select-enable-clipboard is set. > ... but *not* add to kill ring! (unless the user wants it to) As mentioned, that is a separate concern. > No 1 IS a yank, (which via current-kill/interprogram-paste-function) > may pull in CLIPBOARD. The user may prefer C-y to never mess with CLIPBOARD or PRIMARY (and similarly she may want C-k not to mess with either). Stefan ^ permalink raw reply [flat|nested] 66+ messages in thread
* Re: Improving X selection? 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 14:41 ` Improving X selection? Stefan Monnier 0 siblings, 2 replies; 66+ messages in thread From: David De La Harpe Golden @ 2008-02-08 2:50 UTC (permalink / raw) To: Stefan Monnier Cc: Horsley, Tom, Stephen J. Turnbull, Jan D., rms, emacs-devel On 07/02/2008, Stefan Monnier <monnier@iro.umontreal.ca> wrote: >> From what I can tell, there are 4 kinds of selections: > >> - C-SPC + mouse movement. I.e. select-only. > ^^^^^ > cursor > Duh! > > >> - same plus C-w. > >> - selection with the mouse. > >> - one of the above plus "copy" from the menu. > >> > >> No 4 should always use the CLIPBOARD. > >> No 3 should always use the PRIMARY (plus optionally CLIPBOARD) > >> No 2 may optionally use PRIMARY (plus optionally CLIPBOARD) > >> No 1 should use neither or at most PRIMARY. > >> > >> I believe that currently No 2 and No 3 are always handled in the same > >> way, and I don't know if we want to bother separating them. > > > I'm not 100% sure what you meant by "selection with mouse" there : > > No 1 covers "selection [only] with mouse". > > Yes, sorry, the "mouse movement" above was a typo. > Okay, your 2. and 3. are already not necessarily handled the same way in existing emacs - mouse-drag-copy-region nil exists to make mouse-drag selection act like 1 only with the mouse. [Aside: Part of the patch was just to make a setting for mouse-save-then-kill (mouse-3) analogous to mouse-drag-copy-region for mouse-drag... - mouse-save-then-kill-copy-region. Like a standalone fix for select-active-regions, it could be a standalone thing applied independent of rest of patch] So, by setting mouse-drag-copy-region to nil and select-active-regions to t, and sending to CLIPBOARD and kill ring for C-w and to PRIMARY in select-active-regions, outgoing freedesktop.org compliant behaviour can be achieved while unifying the clipboard and kill ring. > >> Why do you need `interprogram-highlight-function'? Can't you just use > >> > >> (let ((x-select-enable-clipboard nil)) > >> (kill-ring-save beg end)) > >> > >> like clipboard-kill-ring-save does? > > > No, that would affect the kill ring! > > Then add x-select-enable-kill-ring. Big deal. > Do you mean as a customization telling select-active-regions not to use kill-ring-save but rather its own call to interprogram-cut-function with the locally rebound x-select-enable-clipboard*? Or telling kill-ring-save to not use the kill ring (heh)? *And, er, then what if the heretic freedesktop.org-scorning user /wants/ selection to affect the clipboard, like an xterm with "select to clipboard" turned on? The patch handles that situation fine. I still think an interprogram-select/insert-function is simpler. Selection and insertion are plain different interprogram operations to cut/copy and paste after all. In fact, outside X11, they're not even interprogram operations. ^ permalink raw reply [flat|nested] 66+ messages in thread
* OT [was Re: Improving X selection?] 2008-02-08 2:50 ` David De La Harpe Golden @ 2008-02-08 13:26 ` Tom Horsley 2008-02-08 15:30 ` David De La Harpe Golden 2008-02-08 14:41 ` Improving X selection? Stefan Monnier 1 sibling, 1 reply; 66+ messages in thread From: Tom Horsley @ 2008-02-08 13:26 UTC (permalink / raw) To: David De La Harpe Golden Cc: Stephen J. Turnbull, Jan D., emacs-devel, Stefan Monnier, rms On Fri, 8 Feb 2008 02:50:44 +0000 "David De La Harpe Golden" <david.delaharpe.golden@gmail.com> wrote: > *And, er, then what if the heretic freedesktop.org-scorning user > /wants/ selection to affect the clipboard, like an xterm with "select > to clipboard" turned on? The patch handles that situation fine. Hey, I just had an idea! I wonder if I could convince my X server that the "atom" for the CLIPBOARD and PRIMARY properties is the same value, then no apps would use two different selections anymore and I wouldn't have to try and keep track of them. Might need a new AtomAlias X server extension for something as nefarious as that :-). ^ permalink raw reply [flat|nested] 66+ messages in thread
* Re: OT [was Re: Improving X selection?] 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 0 siblings, 1 reply; 66+ messages in thread From: David De La Harpe Golden @ 2008-02-08 15:30 UTC (permalink / raw) To: Tom Horsley; +Cc: Stephen J. Turnbull, Jan D., emacs-devel, Stefan Monnier, rms On 08/02/2008, Tom Horsley <tom.horsley@ccur.com> wrote: > On Fri, 8 Feb 2008 02:50:44 +0000 > "David De La Harpe Golden" <david.delaharpe.golden@gmail.com> wrote: > > > *And, er, then what if the heretic freedesktop.org-scorning user > > /wants/ selection to affect the clipboard, like an xterm with "select > > to clipboard" turned on? The patch handles that situation fine. > > Hey, I just had an idea! I wonder if I could convince my X server > that the "atom" for the CLIPBOARD and PRIMARY properties is the > same value, then no apps would use two different selections anymore > and I wouldn't have to try and keep track of them. > Shrug. I'm just not sure what's so tricky about "keeping track" of two different (X11) "selections" (that does _not_ mean "what is currently visually highlighted" in the X11 context) - if you're an emacs user, you're probably doing something similar all the time: Do you have trouble keeping track of active region vs. kill ring in emacs? That's approximately the distinction between primary and clipboard in the freedesktop.org model, after all. Just as it would be annoying to have the active region and kill ring mixed up, people used to freedesktop.org conventions are annoyed by the primary and clipboard being mixed up. ^ permalink raw reply [flat|nested] 66+ messages in thread
* Re: OT 2008-02-08 15:30 ` David De La Harpe Golden @ 2008-02-08 16:07 ` Stefan Monnier 2008-02-08 16:43 ` OT David De La Harpe Golden 0 siblings, 1 reply; 66+ messages in thread From: Stefan Monnier @ 2008-02-08 16:07 UTC (permalink / raw) To: David De La Harpe Golden Cc: Tom Horsley, Stephen J. Turnbull, Jan D., rms, emacs-devel > Do you have trouble keeping track of active region vs. kill ring in emacs? > That's approximately the distinction between primary and clipboard in > the freedesktop.org model, after all. That's the theory. The practice is that every application is slightly different, some offer mouse-1-select and mouse-2-yank, others offer menu-copy and menu-paste, others offer both, others offer those things via keybindings (usually without making it clear which it is), yet others offer those things in a mixed up way with different terminology, ... Yes, if you live exclusively within Gnome or within KDE, you may be able to get a clear mental model, but the Free world predates those things and is much larger than that. I've never *ever* needed to distinguish between the CLIPBOARD and the PRIMARY. The only reason I could ever think of to distinguish them is if you have some braindead application like klipper which eagerly reads whatever's in the CLIPBOARD, even if it's 100MB large on an X11 client connected remotely. Stefan ^ permalink raw reply [flat|nested] 66+ messages in thread
* Re: OT 2008-02-08 16:07 ` OT Stefan Monnier @ 2008-02-08 16:43 ` David De La Harpe Golden 0 siblings, 0 replies; 66+ messages in thread From: David De La Harpe Golden @ 2008-02-08 16:43 UTC (permalink / raw) To: Stefan Monnier; +Cc: Tom Horsley, Stephen J. Turnbull, Jan D., rms, emacs-devel On 08/02/2008, Stefan Monnier <monnier@iro.umontreal.ca> wrote: > That's the theory. The practice is that every application is slightly > different, some offer mouse-1-select and mouse-2-yank, others offer > menu-copy and menu-paste, others offer both, others offer those things > via keybindings (usually without making it clear which it is) Binding issues are different to whether primary/clipboard interaction is different though. It's _much_ more confusing for the underlying interactions with clipboard and primary to be different than for the precise keyboard shortcuts to be different. Thus - for someone used to freedesktop.org behaviour, emacs using: C-w instead of C-x for cut/kill => not particularly confusing, and fixable by cua-mode anyway. C-w affecting primary not clipboard => quite confusing. C-y instead of C-v for paste/yank => not particularly confusing, and fixable by cua-mode anyway. C-y pulling in primary not clipboard => quite confusing. Selection being by C-SPC then cursor-keys instead of shift-cursor-keys => not particularly confusing, and fixable by cua-mode anyway. Selection affecting clipboard not primary => quite confusing. > Yes, if you live exclusively within Gnome or within KDE, you may be able > to get a clear mental model, but the Free world predates those things > and is much larger than that. Undoubtedly, but standardised clipboard interaction is one pretty understandable reason why some people just stop using the predating stuff in favor of stuff that's been updated to the standard model. (N.B. freedesktop.org style interaction is really rather more widely implemented than GNOME and KDE) > I've never *ever* needed to distinguish > between the CLIPBOARD and the PRIMARY. Fine, others do! ^ permalink raw reply [flat|nested] 66+ messages in thread
* Re: Improving X selection? 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 14:41 ` Stefan Monnier 2008-02-08 15:21 ` David De La Harpe Golden 2008-02-17 3:38 ` David De La Harpe Golden 1 sibling, 2 replies; 66+ messages in thread From: Stefan Monnier @ 2008-02-08 14:41 UTC (permalink / raw) To: David De La Harpe Golden Cc: Horsley, Tom, Stephen J. Turnbull, Jan D., rms, emacs-devel > Do you mean as a customization telling select-active-regions not to > use kill-ring-save but rather its own call to > interprogram-cut-function with the locally rebound > x-select-enable-clipboard*? Or telling kill-ring-save to not use the > kill ring (heh)? Not sure how I'd use it, I'd have to look more carefully at the code. But maybe it would be a simple var used for let-binding, and not a defcustom. > I still think an interprogram-select/insert-function is simpler. > Selection and insertion are plain different interprogram operations to > cut/copy and paste after all. In fact, outside X11, they're not even > interprogram operations. I don't think you understand that interprogram-*-function are low-level variables used to dispatch to the appropriate backend (mac/X/w32/...). Stefan ^ permalink raw reply [flat|nested] 66+ messages in thread
* Re: Improving X selection? 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 1 sibling, 0 replies; 66+ messages in thread From: David De La Harpe Golden @ 2008-02-08 15:21 UTC (permalink / raw) To: Stefan Monnier Cc: Horsley, Tom, Stephen J. Turnbull, Jan D., rms, emacs-devel On 08/02/2008, Stefan Monnier <monnier@iro.umontreal.ca> wrote: > > Do you mean as a customization telling select-active-regions not to > > use kill-ring-save but rather its own call to > > interprogram-cut-function with the locally rebound > > x-select-enable-clipboard*? Or telling kill-ring-save to not use the > > kill ring (heh)? > > Not sure how I'd use it, I'd have to look more carefully at the code. > But maybe it would be a simple var used for let-binding, and not > a defcustom. > > > I still think an interprogram-select/insert-function is simpler. > > Selection and insertion are plain different interprogram operations to > > cut/copy and paste after all. In fact, outside X11, they're not even > > interprogram operations. > > I don't think you understand that interprogram-*-function are low-level > variables used to dispatch to the appropriate backend (mac/X/w32/...). > I understand that. Trouble is, you seem to want to use interprogram-cut for thigns that are not [supposed to be] cut/copy operations at the backend/OS level and interprogram-paste for things that are not [supposed to be] paste operations at the backend/OS level. Look, if the operations aren't confused, it's easy enough to provide a user preference to confuse them if they like the historic emacs behaviours. If they start off confused, it's difficult to impossible to subsequently unconfuse them. Calling (or considering the functions to be) really interprogram-input-function and interprogram-output-function that take parameters or use locally rebound variables to indicate what sort of input or output operation it really is could kind of work, but would likely encourage just the sort of historic confusion it would be nice to avoid in future (if emacs fitting in with a freedesktop.org desktop is a goal). ^ permalink raw reply [flat|nested] 66+ messages in thread
* Re: Improving X selection? 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 1 sibling, 1 reply; 66+ messages in thread From: David De La Harpe Golden @ 2008-02-17 3:38 UTC (permalink / raw) To: Stefan Monnier Cc: Horsley, Tom, Stephen J. Turnbull, Jan D., rms, emacs-devel [-- Attachment #1: Type: text/plain, Size: 4034 bytes --] On 08/02/2008, Stefan Monnier <monnier@iro.umontreal.ca> wrote: > > Do you mean as a customization telling select-active-regions not to > > use kill-ring-save but rather its own call to > > interprogram-cut-function with the locally rebound > > x-select-enable-clipboard*? Or telling kill-ring-save to not use the > > kill ring (heh)? > > Not sure how I'd use it, I'd have to look more carefully at the code. > But maybe it would be a simple var used for let-binding, and not > a defcustom. > Anyhow, here's a stab at doing it Stefan's way... Rev 3. patch has an enable-kill-ring, a boolean var that (um) acts at the core, current-kill and kill-new. It's not itself a customization, but specific-situation overrides of it with active-region-enable-kill-ring and mouse-yank-enable-kill-ring are. (assumed people would always want to use the kill ring in keyboard and menu/tool-bar killing/yanking...). Patch introduces a number of boolean customizations: ;; for "default" (C-w/C-y) killing/yanking enable-system-clipboard enable-system-current-selection ;; override defaults for mouse yanking mouse-yank-enable-system-clipboard mouse-yank-enable-system-current-selection mouse-yank-enable-kill-ring ;; override defaults for active region propagation to system ;; what was "select-active-regions" active-region-enable-system-clipboard active-region-enable-system-current-selection active-region-enable-kill-ring ;; override for yank-pop propagations to system. ;; what was "yank-pop-change-selection" yank-pop-change-system-clipboard yank-pop-change-system-current-selection ;; override for menu-bar (when menu-enable-clipboard has been called.) menu-bar-enable-system-clipboard menu-bar-enable-system-current-selection ;; for deciding what "system-clipboard" and "system-current-selection" ;; actually mean in X11 terms, for those who dislike recent-X11-style ;; and/or other compat with other programs that dislike or predate it. x-system-clipboard-is-x-selection x-system-current-selection-is-x-selection As per comments in this thread and for clarity, I've de-platform-specialized and renamed x-select-enable-clipboard/x-select-enable-primary, according to how a user used to recent-X11-style would perceive them, and tried to use "selection" to mean "what the user has selected", not "x selection". Then, to try to keep everyone happy, there is an extra layer of indirection to allow you to specify what the de-platform-specialized variables then actually mean on an X level - i.e. when, when the user says "enable-system-clipboard", do they mean primary, clipboard or cutbuffer, and similarly for "enable-system-current-selection". This patch doesn't try to do multiple-selection-return - doing it would mean a bit more of an alteration to x-cut-buffer-or-selection-value. The customization defaults in this patch should produce behaviour matching or nearly matching (menus may be slightly different) current default emacs behaviour. Unlike rev.2, while the full spectrum of possible historic emacs behaviours should be possible in addition to the desired new behaviour, it now takes somewhat different customizations to get them - but customization is clearer. term/ impls other than x-win are not updated to use the model (but that should be straightforward in itself, typical platforms only have a system-clipboard in the first place). To get the recent-X11-style behaviour from it: (custom-set-variables '(active-region-enable-kill-ring nil) '(active-region-enable-system-clipboard nil) '(active-region-enable-system-current-selection t) '(enable-system-clipboard t) '(enable-system-current-selection nil) '(menu-bar-enable-system-clipboard t) '(menu-bar-enable-system-current-selection nil) '(mouse-drag-copy-region nil) '(mouse-yank-enable-kill-ring nil) '(mouse-yank-enable-system-clipboard nil) '(mouse-yank-enable-system-current-selection t) '(transient-mark-mode t) '(x-system-clipboard-is-x-selection (quote (:clipboard))) '(x-system-current-selection-is-x-selection (quote (:primary)))) [-- Warning: decoded text below may be mangled, UTF-8 assumed --] [-- Attachment #2: enhanced-x-selections_rev3.diff --] [-- Type: text/x-diff; name=enhanced-x-selections_rev3.diff, Size: 36374 bytes --] Index: lisp/loadup.el =================================================================== RCS file: /sources/emacs/emacs/lisp/loadup.el,v retrieving revision 1.160 diff -U 8 -r1.160 loadup.el --- lisp/loadup.el 1 Feb 2008 22:43:10 -0000 1.160 +++ lisp/loadup.el 17 Feb 2008 03:01:28 -0000 @@ -77,16 +77,17 @@ (load "button") (load "startup") (message "Lists of integers (garbage collection statistics) are normal output") (message "while building Emacs; they do not indicate a problem.") (message "%s" (garbage-collect)) (load "loaddefs.el") ;Don't get confused if someone compiled this by mistake. (message "%s" (garbage-collect)) +(load "emacs-lisp/timer") ; needed for propagate-active-region in simple (load "simple") (load "help") (load "jka-cmpr-hook") ;; Any Emacs Lisp source file (*.el) loaded here after can contain ;; multilingual text. (load "international/mule-cmds") @@ -140,17 +141,16 @@ (load "jit-lock") (if (fboundp 'track-mouse) (progn (load "mouse") (and (boundp 'x-toolkit-scroll-bars) (load "scroll-bar")) (load "select"))) -(load "emacs-lisp/timer") (load "isearch") (load "rfn-eshadow") (message "%s" (garbage-collect)) (load "menu-bar") (load "paths.el") ;Don't get confused if someone compiled paths by mistake. (load "emacs-lisp/lisp") (load "textmodes/page") Index: lisp/w32-vars.el =================================================================== RCS file: /sources/emacs/emacs/lisp/w32-vars.el,v retrieving revision 1.19 diff -U 8 -r1.19 w32-vars.el --- lisp/w32-vars.el 8 Jan 2008 20:44:48 -0000 1.19 +++ lisp/w32-vars.el 17 Feb 2008 03:01:28 -0000 @@ -144,18 +144,20 @@ (repeat :inline t (choice :tag "" (const :tag "Separator" ("")) (list :tag "Font Entry" (string :tag "Menu text") (string :tag "Font"))))))) :group 'w32) -(defcustom x-select-enable-clipboard t - "*Non-nil means cutting and pasting uses the clipboard. -This is in addition to the primary selection." - :type 'boolean - :group 'killing) +;; There is now a enable-system-clipboard flag in simple.el +;; +;;(defcustom x-select-enable-clipboard t +;; "*Non-nil means cutting and pasting uses the clipboard. +;;This is in addition to the primary selection." +;; :type 'boolean +;; :group 'killing) (provide 'w32-vars) ;;; arch-tag: ee2394fb-9db7-4c15-a8f0-66b47f4a2bb1 ;;; w32-vars.el ends here Index: lisp/simple.el =================================================================== RCS file: /sources/emacs/emacs/lisp/simple.el,v retrieving revision 1.901 diff -U 8 -r1.901 simple.el --- lisp/simple.el 12 Feb 2008 02:25:08 -0000 1.901 +++ lisp/simple.el 17 Feb 2008 03:01:34 -0000 @@ -2544,28 +2544,31 @@ (if noprops (set-text-properties 0 (length string) nil string)) string))) (noprops (buffer-substring-no-properties beg end)) (t (buffer-substring beg end)))) - ;;;; Window system cut and paste hooks. (defvar interprogram-cut-function nil "Function to call to make a killed region available to other programs. Most window systems provide some sort of facility for cutting and pasting text between the windows of different programs. This variable holds a function that Emacs calls whenever text is put in the kill ring, to make the new kill available to other programs. +This function should respect `enable-system-clipboard' and +`enable-system-current-selection' if possible. It may also honour +the value of window-system-specific customisations. + The function takes one or two arguments. The first argument, TEXT, is a string containing the text which should be made available. The second, optional, argument PUSH, has the same meaning as the similar argument to `x-set-cut-buffer', which see.") (defvar interprogram-paste-function nil "Function to call to get text cut from other programs. @@ -2581,22 +2584,28 @@ string, then the caller of the function \(usually `current-kill') should put this string in the kill ring as the latest kill. This function may also return a list of strings if the window system supports multiple selections. The first string will be used as the pasted text, but the other will be placed in the kill ring for easy access via `yank-pop'. -Note that the function should return a string only if a program other -than Emacs has provided a string for pasting; if Emacs provided the -most recent string, the function should return nil. If it is -difficult to tell whether Emacs or some other program provided the -current string, it is probably good enough to return nil if the string -is equal (according to `string=') to the last text Emacs provided.") +This function should respect `enable-system-clipboard' and +`enable-system-current-selection' if possible. It may also honour +the value of window-system-specific customisations. + +Note that, unless `enable-kill-ring' is nil, the function should +return a string only if a program other than Emacs has provided a +string for pasting; if Emacs provided the most recent string, the +function should return nil. If `enable-kill-ring' is nil, the +function should just always return what it finds, if anything. +If it is difficult to tell whether Emacs or some other program provided +the current string, it is probably good enough to return nil if the +string is equal (according to `string=') to the last text Emacs provided.") \f ;;;; The kill ring data structure. (defvar kill-ring nil "List of killed text sequences. Since the kill ring is supposed to interact nicely with cut-and-paste @@ -2607,50 +2616,76 @@ interaction; you may want to use them instead of manipulating the kill ring directly.") (defcustom kill-ring-max 60 "*Maximum length of kill ring before oldest elements are thrown away." :type 'integer :group 'killing) +(defcustom enable-system-clipboard nil + "Non-nil means emacs killing and yanking uses the system clipboard." + :type 'boolean + :group 'killing + :version "23.1") + +(defcustom enable-system-current-selection t + "Non-nil means emacs killing and yanking uses the system current selection. +Your windowing system may not provide a current selection tracking +facility. If it doesn't, emacs may or may not emulate it." + :type 'boolean + :group 'killing + :version "23.1") + (defvar kill-ring-yank-pointer nil "The tail of the kill ring whose car is the last thing yanked.") +(defvar enable-kill-ring t + "If nil, then 'killing' won't actually affect the kill ring +and 'yanking' won't actually draw on or affect the kill ring. +Only `interprogram-cut-function' and `interprogram-paste-function' +will be used. This is useful for conforming to X11 desktop +conventions.") + (defun kill-new (string &optional replace yank-handler) "Make STRING the latest kill in the kill ring. Set `kill-ring-yank-pointer' to point to it. If `interprogram-cut-function' is non-nil, apply it to STRING. Optional second argument REPLACE non-nil means that STRING will replace the front of the kill ring, rather than being added to the list. +If variable `enable-kill-ring' is nil, then this function +will not affect the kill ring, but `interprogram-cut-function' may +be called. + Optional third arguments YANK-HANDLER controls how the STRING is later inserted into a buffer; see `insert-for-yank' for details. When a yank handler is specified, STRING must be non-empty (the yank handler, if non-nil, is stored as a `yank-handler' text property on STRING). When the yank handler has a non-nil PARAM element, the original STRING argument is not used by `insert-for-yank'. However, since Lisp code may access and use elements from the kill ring directly, the STRING argument should still be a \"useful\" string for such uses." - (if (> (length string) 0) + (when enable-kill-ring + (if (> (length string) 0) + (if yank-handler + (put-text-property 0 (length string) + 'yank-handler yank-handler string)) (if yank-handler - (put-text-property 0 (length string) - 'yank-handler yank-handler string)) - (if yank-handler - (signal 'args-out-of-range - (list string "yank-handler specified for empty string")))) - (if (fboundp 'menu-bar-update-yank-menu) - (menu-bar-update-yank-menu string (and replace (car kill-ring)))) - (if (and replace kill-ring) - (setcar kill-ring string) - (push string kill-ring) - (if (> (length kill-ring) kill-ring-max) - (setcdr (nthcdr (1- kill-ring-max) kill-ring) nil))) - (setq kill-ring-yank-pointer kill-ring) + (signal 'args-out-of-range + (list string "yank-handler specified for empty string")))) + (if (fboundp 'menu-bar-update-yank-menu) + (menu-bar-update-yank-menu string (and replace (car kill-ring)))) + (if (and replace kill-ring) + (setcar kill-ring string) + (push string kill-ring) + (if (> (length kill-ring) kill-ring-max) + (setcdr (nthcdr (1- kill-ring-max) kill-ring) nil))) + (setq kill-ring-yank-pointer kill-ring)) (if interprogram-cut-function (funcall interprogram-cut-function string (not replace)))) (defun kill-append (string before-p &optional yank-handler) "Append STRING to the end of the latest kill in the kill ring. If BEFORE-P is non-nil, prepend STRING to the kill. Optional third argument YANK-HANDLER, if non-nil, specifies the yank-handler text property to be set on the combined kill ring @@ -2660,63 +2695,81 @@ instead of replacing the last kill with it. If `interprogram-cut-function' is set, pass the resulting kill to it." (let* ((cur (car kill-ring))) (kill-new (if before-p (concat string cur) (concat cur string)) (or (= (length cur) 0) (equal yank-handler (get-text-property 0 'yank-handler cur))) yank-handler))) -(defcustom yank-pop-change-selection nil + +(defcustom yank-pop-change-system-current-selection nil "If non-nil, rotating the kill ring changes the window system selection." :type 'boolean :group 'killing :version "23.1") +(defcustom yank-pop-change-system-clipboard nil + "If non-nil, rotating the kill ring changes the window system clipboard" + :type 'boolean + :group 'killing + :version "23.1") + (defun current-kill (n &optional do-not-move) "Rotate the yanking point by N places, and then return that kill. If N is zero, `interprogram-paste-function' is set, and calling it returns a string or list of strings, then that string (or list) is added to the front of the kill ring and the string (or first string in the list) is returned as -the latest kill. +the latest kill. However, if variable `enable-kill-ring' is +nil, then the kill ring will not be affected, nor will it be used to find +the yanked text - only `interprogram-paste-function' will be used. If N is not zero, and if `yank-pop-change-selection' is non-nil, use `interprogram-cut-function' to transfer the kill at the new yank point into the window system selection. + If optional arg DO-NOT-MOVE is non-nil, then don't actually move the yanking point; just return the Nth kill forward." (let ((interprogram-paste (and (= n 0) interprogram-paste-function (funcall interprogram-paste-function)))) - (if interprogram-paste + (if enable-kill-ring (progn - ;; Disable the interprogram cut function when we add the new - ;; text to the kill ring, so Emacs doesn't try to own the - ;; selection, with identical text. - (let ((interprogram-cut-function nil)) - (if (listp interprogram-paste) - (mapc 'kill-new (nreverse interprogram-paste)) - (kill-new interprogram-paste))) - (car kill-ring)) - (or kill-ring (error "Kill ring is empty")) - (let ((ARGth-kill-element - (nthcdr (mod (- n (length kill-ring-yank-pointer)) - (length kill-ring)) - kill-ring))) - (unless do-not-move - (setq kill-ring-yank-pointer ARGth-kill-element) - (when (and yank-pop-change-selection - (> n 0) - interprogram-cut-function) - (funcall interprogram-cut-function (car ARGth-kill-element)))) - (car ARGth-kill-element))))) - - + (if interprogram-paste + (progn + ;; Disable the interprogram cut function when we add the new + ;; text to the kill ring, so Emacs doesn't try to own the + ;; selection, with identical text. + (let ((interprogram-cut-function nil)) + (if (listp interprogram-paste) + (mapc 'kill-new (nreverse interprogram-paste)) + (kill-new interprogram-paste))) + (car kill-ring)) + (or kill-ring (error "Kill ring is empty")) + (let ((ARGth-kill-element + (nthcdr (mod (- n (length kill-ring-yank-pointer)) + (length kill-ring)) + kill-ring))) + (unless do-not-move + (setq kill-ring-yank-pointer ARGth-kill-element) + (when (and (or yank-pop-change-system-current-selection + yank-pop-change-system-clipboard) + (> n 0) + interprogram-cut-function) + (let ((enable-system-clipboard yank-pop-change-system-clipboard) + (enable-system-current-selection yank-pop-change-system-current-selection)) + (funcall interprogram-cut-function (car ARGth-kill-element))))) + (car ARGth-kill-element)))) + (if interprogram-paste + (if (listp interprogram-paste) + (car interprogram-paste) + interprogram-paste) + (error "No system selections found and kill ring is off for this operation."))))) ;;;; Commands for manipulating the kill ring. (defcustom kill-read-only-ok nil "*Non-nil means don't signal an error for killing read-only text." :type 'boolean :group 'killing) @@ -3305,35 +3358,93 @@ is active, and returns an integer or nil in the usual way. If you are using this in an editing command, you are most likely making a mistake; see the documentation of `set-mark'." (if (or force (not transient-mark-mode) mark-active mark-even-if-inactive) (marker-position (mark-marker)) (signal 'mark-inactive nil))) +(defvar propagate-active-region-last-region nil + "record of last propagated region for comparison +in `propagate-active-region'") + +(defvar propagate-active-region-replace nil + "used to trim kill-ring growth in propagate-active-region, +for when active-region-enable-kill-ring is non-nil.") + ;; Many places set mark-active directly, and several of them failed to also ;; run deactivate-mark-hook. This shorthand should simplify. (defsubst deactivate-mark () "Deactivate the mark by setting `mark-active' to nil. \(That makes a difference only in Transient Mark mode.) Also runs the hook `deactivate-mark-hook'." + (cancel-function-timers 'propagate-active-region) + (setq propagate-active-region-replace nil) + (setq propagate-active-region-last-region nil) (cond ((eq transient-mark-mode 'lambda) (setq transient-mark-mode nil)) (transient-mark-mode (setq mark-active nil) (run-hooks 'deactivate-mark-hook)))) -(defcustom select-active-regions nil - "If non-nil, an active region automatically becomes the window selection." + +(defcustom active-region-enable-system-clipboard nil + "If non-nil, an active region automatically updates the system clipboard. +This happens without any explicit kill." + :type 'boolean + :group 'killing + :version "23.1") + +(defcustom active-region-enable-system-current-selection nil + "If non-nil, an active region automatically updates the system current selection. +This happens without any explicit kill." :type 'boolean :group 'killing :version "23.1") +(defcustom active-region-enable-kill-ring nil + "If non-nil, an active region automatically becomes head of the kill ring. +This happens without any explicit kill." + :type 'boolean + :group 'killing + :version "23.1") + + +(defun propagate-active-region () + "Implements `active-regions-enable-system-clipboard' + + Called by an idle timer active when region is active and `set-mark'" + (and (or active-region-enable-system-clipboard + active-region-enable-system-current-selection + active-region-enable-kill-ring) + (region-active-p) + (let ((maybe-propagate-current-region-text + (buffer-substring (region-beginning) (region-end)))) + (when (or (null propagate-active-region-last-region) + (not (string= propagate-active-region-last-region + maybe-propagate-current-region-text))) + (setq propagate-active-region-last-region + maybe-propagate-current-region-text) + (if (or (null maybe-propagate-current-region-text) + (string= "" maybe-propagate-current-region-text)) + ;; don't propagate if this region is empty, but this + ;; region being empty means future nonempty regions + ;; need repropagation + (setq propagate-active-region-last-region nil) + (let ((enable-system-clipboard active-region-enable-system-clipboard) + (enable-system-current-selection + active-region-enable-system-current-selection) + (enable-kill-ring active-region-enable-kill-ring)) + (kill-new maybe-propagate-current-region-text + propagate-active-region-replace) + (setq propagate-active-region-replace t))))))) + + (defun set-mark (pos) "Set this buffer's mark to POS. Don't use this function! That is to say, don't use this function unless you want the user to see that the mark has moved, and you want the previous mark position to be lost. Normally, when a new mark is set, the old one should go on the stack. This is why most applications should use `push-mark', not `set-mark'. @@ -3345,19 +3456,25 @@ store it in a Lisp variable. Example: (let ((beg (point))) (forward-line 1) (delete-region beg (point)))." (if pos (progn (setq mark-active t) (run-hooks 'activate-mark-hook) - (and select-active-regions - (x-set-selection - nil (buffer-substring (region-beginning) (region-end)))) + (when (or active-region-enable-system-clipboard + active-region-enable-system-current-selection + active-region-enable-kill-ring) + (cancel-function-timers 'propagate-active-region) + (run-with-idle-timer 0 t + 'propagate-active-region) + ; force immediate repropagate if mark is reset + (setq propagate-active-region-last-region nil) + (propagate-active-region)) (set-marker (mark-marker) pos (current-buffer))) ;; Normally we never clear mark-active except in Transient Mark mode. ;; But when we actually clear out the mark value too, ;; we must clear mark-active in any mode. (setq mark-active nil) (run-hooks 'deactivate-mark-hook) (set-marker (mark-marker) nil))) Index: lisp/mouse.el =================================================================== RCS file: /sources/emacs/emacs/lisp/mouse.el,v retrieving revision 1.327 diff -U 8 -r1.327 mouse.el --- lisp/mouse.el 7 Feb 2008 06:20:25 -0000 1.327 +++ lisp/mouse.el 17 Feb 2008 03:01:37 -0000 @@ -1351,30 +1351,52 @@ (mouse-minibuffer-check click) (let* ((posn (event-start click)) (click-posn (posn-point posn))) (select-window (posn-window posn)) (if (numberp click-posn) (kill-region (min (point) click-posn) (max (point) click-posn))))) +(defcustom mouse-yank-enable-system-clipboard nil + "If non-nil, \\[mouse-yank-at-click] uses the system clipboard." + :type 'boolean + :group 'mouse + :version "23.1") + +(defcustom mouse-yank-enable-system-current-selection t + "If non-nil, \\[mouse-yank-at-click] uses the system current selection." + :type 'boolean + :group 'mouse + :version "23.1") + +(defcustom mouse-yank-enable-kill-ring t + "If non-nil, \\[mouse-yank-at-click] uses the kill ring." + :type 'boolean + :group 'mouse + :version "23.1") + (defun mouse-yank-at-click (click arg) "Insert the last stretch of killed text at the position clicked on. Also move point to one end of the text thus inserted (normally the end), and set mark at the beginning. Prefix arguments are interpreted as with \\[yank]. If `mouse-yank-at-point' is non-nil, insert at point regardless of where you click." (interactive "e\nP") ;; 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)) - (setq this-command 'yank) - (setq mouse-selection-click-count 0) - (yank arg)) + (let ((enable-kill-ring mouse-yank-enable-kill-ring) + (enable-system-clipboard mouse-yank-enable-system-clipboard) + (enable-system-current-selection + mouse-yank-enable-system-current-selection)) + (setq this-command 'yank) + (setq mouse-selection-click-count 0) + (yank arg))) (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. Index: lisp/menu-bar.el =================================================================== RCS file: /sources/emacs/emacs/lisp/menu-bar.el,v retrieving revision 1.318 diff -U 8 -r1.318 menu-bar.el --- lisp/menu-bar.el 8 Jan 2008 20:44:39 -0000 1.318 +++ lisp/menu-bar.el 17 Feb 2008 03:01:39 -0000 @@ -508,32 +508,51 @@ '(and mark-active (not buffer-read-only))) (put 'clipboard-kill-ring-save 'menu-enable 'mark-active) (put 'clipboard-yank 'menu-enable '(and (or (and (fboundp 'x-selection-exists-p) (x-selection-exists-p)) (x-selection-exists-p 'CLIPBOARD)) (not buffer-read-only))) + +(defcustom menu-bar-enable-system-clipboard t + "If non-nil, menu bar cut/copy/paste uses the system clipboard." + :type 'boolean + :group 'menu + :version "23.1") + +(defcustom menu-bar-enable-system-current-selection nil + "If non-nil, menu bar cut/copy/paste uses the system current selection." + :type 'boolean + :group 'menu + :version "23.1") + (defun clipboard-yank () "Insert the clipboard contents, or the last stretch of killed text." (interactive "*") - (let ((x-select-enable-clipboard t)) + (let ((enable-system-clipboard menu-bar-enable-system-clipboard) + (enable-system-current-selection + menu-bar-enable-system-current-selection)) (yank))) (defun clipboard-kill-ring-save (beg end) "Copy region to kill ring, and save in the X clipboard." (interactive "r") - (let ((x-select-enable-clipboard t)) + (let ((enable-system-clipboard menu-bar-enable-system-clipboard) + (enable-system-current-selection + menu-bar-enable-system-current-selection)) (kill-ring-save beg end))) (defun clipboard-kill-region (beg end) "Kill the region, and save it in the X clipboard." (interactive "r") - (let ((x-select-enable-clipboard t)) + (let ((enable-system-clipboard menu-bar-enable-system-clipboard) + (enable-system-current-selection + menu-bar-enable-system-current-selection)) (kill-region beg end))) (defun menu-bar-enable-clipboard () "Make CUT, PASTE and COPY (keys and menu bar items) use the clipboard. Do the same for the keys of the same name." (interactive) ;; We can't use constant list structure here because it becomes pure, ;; and because it gets modified with cache data. Index: lisp/term/x-win.el =================================================================== RCS file: /sources/emacs/emacs/lisp/term/x-win.el,v retrieving revision 1.224 diff -U 8 -r1.224 x-win.el --- lisp/term/x-win.el 8 Feb 2008 08:33:23 -0000 1.224 +++ lisp/term/x-win.el 17 Feb 2008 03:01:41 -0000 @@ -2150,52 +2150,76 @@ This is the actual text stored in the X cut buffer.") (defvar x-last-cut-buffer-coding 'iso-latin-1 "The coding we last used to encode/decode the text from the X cut buffer") (defvar x-cut-buffer-max 20000 ; Note this value is overridden below. "Max number of characters to put in the cut buffer. It is said that overlarge strings are slow to put into the cut buffer.") -(defcustom x-select-enable-clipboard nil - "Non-nil means cutting and pasting uses the clipboard. -This is in addition to, but in preference to, the primary selection." - :type 'boolean - :group 'killing) - -(defcustom x-select-enable-primary t - "Non-nil means cutting and pasting uses the primary selection." - :type 'boolean - :group 'killing) + +;; A special layer of indirection on X11 to keep +;; the freedesktop.org averse happy and indicate +;; if legacy cutbuffers should be used. Other platforms +;; ...probably don't need this. + +(defcustom x-system-clipboard-is-x-selection '(:clipboard) + "Which X Selection(s) mean the 'system clipboard'." + :type '(set (const :clipboard) + (const :primary) + (const :cutbuffer)) + :group 'x + :version "23.1") + +(defcustom x-system-current-selection-is-x-selection '(:primary :cutbuffer) + "Which X Selection(s) mean the 'system current selection'." + :type '(set (const :clipboard) + (const :primary) + (const :cutbuffer)) + :group 'x + :version "23.1") + +(defun use-x-selection-p (sel) + "Test if x-level selection or cutbuffer should be +used according to `enable-system-clipboard', +`enable-system-current-selection' matched against +`x-system-clipboard-is-x-selection' and +`x-system-current-selection-is-x-selection'" +(or + (when enable-system-clipboard + (memq sel x-system-clipboard-is-x-selection)) + (when enable-system-current-selection + (memq sel x-system-current-selection-is-x-selection)))) (defun x-select-text (text &optional push) "Make TEXT, a string, the primary X selection. Also, set the value of X cut buffer 0, for backward compatibility with older X applications. gildea@stop.mail-abuse.org says it's not desirable to put kills in the clipboard." ;; With multi-tty, this function may be called from a tty frame. (when (eq (framep (selected-frame)) 'x) - ;; 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 + (when (use-x-selection-p :cutbuffer) + ;; 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 (use-x-selection-p :primary) (x-set-selection 'PRIMARY text) (setq x-last-selected-text-primary text)) - (when x-select-enable-clipboard + (when (use-x-selection-p :clipboard) (x-set-selection 'CLIPBOARD text) (setq x-last-selected-text-clipboard text)))) (defvar x-select-request-type nil "*Data type request for X selection. The value is one of the following data types, a list of them, or nil: `COMPOUND_TEXT', `UTF8_STRING', `STRING', `TEXT' @@ -2236,84 +2260,91 @@ ;; 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 () ;; With multi-tty, this function may be called from a tty frame. (when (eq (framep (selected-frame)) 'x) (let (clip-text primary-text cut-text) - (when x-select-enable-clipboard + (when (use-x-selection-p :clipboard) (setq clip-text (x-selection-value 'CLIPBOARD)) (if (string= clip-text "") (setq clip-text nil)) + + (when enable-kill-ring + ;; 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)))))) - ;; 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 + (when (use-x-selection-p :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) + (if (string= primary-text "") (setq primary-text nil)) + (when enable-kill-ring + ;; 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)))))) + + (when (use-x-selection-p :cutbuffer) + (setq cut-text (x-get-cut-buffer 0)) + (if (string= cut-text "") (setq cut-text nil)) + + ;; 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) + (if enable-kill-ring + nil + cut-text)) + (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 @@ -2332,25 +2363,16 @@ ;; checked again). (or clip-text primary-text cut-text) ))) ;; Arrange for the kill and yank functions to set and check the clipboard. (setq interprogram-cut-function 'x-select-text) (setq interprogram-paste-function 'x-cut-buffer-or-selection-value) -(defun x-clipboard-yank () - "Insert the clipboard contents, or the last stretch of killed text." - (interactive "*") - (let ((clipboard-text (x-selection-value 'CLIPBOARD)) - (x-select-enable-clipboard t)) - (if (and clipboard-text (> (length clipboard-text) 0)) - (kill-new clipboard-text)) - (yank))) - (defun x-menu-bar-open (&optional frame) "Open the menu bar if `menu-bar-mode' is on. otherwise call `tmm-menubar'." (interactive "i") (if menu-bar-mode (accelerate-menu frame) (tmm-menubar))) \f ;;; Window system initialization. @@ -2455,23 +2477,16 @@ ;; (global-set-key [f10] 'ignore)) ;; Turn on support for mouse wheels. (mouse-wheel-mode 1) ;; Enable CLIPBOARD copy/paste through menu bar commands. (menu-bar-enable-clipboard) - ;; Override Paste so it looks at CLIPBOARD first. - (define-key menu-bar-edit-menu [paste] - (append '(menu-item "Paste" x-clipboard-yank - :enable (not buffer-read-only) - :help "Paste (yank) text most recently cut/copied") - nil)) - (setq x-initialized t)) (add-to-list 'handle-args-function-alist '(x . x-handle-args)) (add-to-list 'frame-creation-function-alist '(x . x-create-frame-with-faces)) (add-to-list 'window-system-initialization-alist '(x . x-initialize-window-system)) ;; Initiate drag and drop (add-hook 'after-make-frame-functions 'x-dnd-init-frame) ^ permalink raw reply [flat|nested] 66+ messages in thread
* Re: Improving X selection? 2008-02-17 3:38 ` David De La Harpe Golden @ 2008-02-17 3:55 ` David De La Harpe Golden 0 siblings, 0 replies; 66+ messages in thread From: David De La Harpe Golden @ 2008-02-17 3:55 UTC (permalink / raw) To: Stefan Monnier Cc: Horsley, Tom, Stephen J. Turnbull, Jan D., rms, emacs-devel [-- Attachment #1: Type: text/plain, Size: 221 bytes --] Rev 3 is missing the move of deactivate-mark to before point move in mouse-drag-track that was in rev.2, needs attached patch (well, still not clear if idle timer can ever be called while dragging underway, but if so...) [-- Warning: decoded text below may be mangled, UTF-8 assumed --] [-- Attachment #2: mouse-drag-track-deactivate-mark-before-move-point.diff --] [-- Type: text/x-diff; name=mouse-drag-track-deactivate-mark-before-move-point.diff, Size: 717 bytes --] --- lisp/mouse.el +++ lisp/mouse.el @@ -927,6 +927,7 @@ should only be used by mouse-drag-region." (mouse-minibuffer-check start-event) (setq mouse-selection-click-count-buffer (current-buffer)) + (deactivate-mark) (let* ((original-window (selected-window)) ;; We've recorded what we needed from the current buffer and ;; window, now let's jump to the place of the event, where things @@ -971,7 +972,6 @@ (mouse-move-drag-overlay mouse-drag-overlay start-point start-point click-count) (overlay-put mouse-drag-overlay 'window start-window) - (deactivate-mark) (let (event end end-point last-end-point) (track-mouse (while (progn ^ permalink raw reply [flat|nested] 66+ messages in thread
* Re: Improving X selection? 2008-02-07 19:45 ` Stefan Monnier 2008-02-07 20:39 ` 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 22:51 ` Stefan Monnier 1 sibling, 2 replies; 66+ messages in thread From: Tom Horsley @ 2008-02-07 21:01 UTC (permalink / raw) To: Stefan Monnier Cc: David De La Harpe Golden, Jan D., emacs-devel, Stephen J. Turnbull, rms On Thu, 07 Feb 2008 14:45:46 -0500 Stefan Monnier <monnier@iro.umontreal.ca> wrote: > For all three cases, the first question is "where does the text come from": > No 3 should always use the CLIPBOARD then PRIMARY then kill ring. > No 2 should use the CLIPBOARD only if x-select-enable-clipboard is set. > No 1 is identical except it may also not check PRIMARY either. This is, of course, totally a matter of opinion, and is the reason the complication exists for those of us who have other opinions. For instance, I talk to a lot of systems which only have xterm as the interface. Xterm only does PRIMARY. If you examine the algorithm you just described, it is almost impossible to obtain PRIMARY if a CLIPBOARD exists anywhere else. The fact that emacs works that way was the primary motivation for my original message all those months ago. There is also another deeper philosophical issue: the question of the value of two different selections which are visually identical. I happen to think the invention of CLIPBOARD was perhaps the single most brain damaged idea ever foisted upon users by the singularly brain damaged group of folks who call themselves freedesktop, that's my opinion, which I guess is a minority one, but why shouldn't I be able to configure my emacs to make the difference almost indistinguishable? That's what emacs is about. By all means make the default conform to whatever standard you want to pick, but don't make it impossibly difficult for people with different ideas to work a different way :-). My way is: emacs sets both CLIPBOARD and PRIMARY however I make the selection (so I don't have to mentally keep track of which selection has the pea under it :-), and paste operations of any kind put all the different selections into the kill ring, so if I see the wrong text got pasted, a yank-pop will get me the right text. With the price of an occasional yank-pop, I can almost eradicate the difference bwtween PRIMARY and CLIPBOARD. ^ permalink raw reply [flat|nested] 66+ messages in thread
* Re: Improving X selection? 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 22:51 ` Stefan Monnier 1 sibling, 1 reply; 66+ messages in thread From: David De La Harpe Golden @ 2008-02-07 21:18 UTC (permalink / raw) To: Tom Horsley; +Cc: Stephen J. Turnbull, Jan D., emacs-devel, Stefan Monnier, rms On 07/02/2008, Tom Horsley <tom.horsley@ccur.com> wrote: > Xterm only does PRIMARY. FWIW, that's not true of at least vaguely recent xterm - Holding down ctrl-middlemouse should bring up a menu with a "select to clipboard" option. > I happen to think the invention of CLIPBOARD was perhaps the single > most brain damaged idea ever foisted upon users by the singularly > brain damaged group of folks who call themselves freedesktop, I realise that's probably slightly tongue in cheek, but CLIPBOARD long pre-dates the freedesktop effort AFAIK. Some of the same people might be involved I guess. ^ permalink raw reply [flat|nested] 66+ messages in thread
* Re: Improving X selection? 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 0 siblings, 1 reply; 66+ messages in thread From: Tom Horsley @ 2008-02-07 21:36 UTC (permalink / raw) To: David De La Harpe Golden Cc: Stephen J. Turnbull, Jan D., emacs-devel, Stefan Monnier, rms On Thu, 7 Feb 2008 21:18:43 +0000 "David De La Harpe Golden" <david.delaharpe.golden@gmail.com> wrote: > On 07/02/2008, Tom Horsley <tom.horsley@ccur.com> wrote: > > > Xterm only does PRIMARY. > > FWIW, that's not true of at least vaguely recent xterm - Holding down > ctrl-middlemouse should bring up a menu with a "select to clipboard" > option. Yuck. Perhaps I should have said it might as well only do PRIMARY, if I tie my fingers in knots I can get CLIPBOARD :-). Also I have no idea what vintage xterms are on some of the platforms I access, some of them are pretty old. > > I happen to think the invention of CLIPBOARD was perhaps the single > > most brain damaged idea ever foisted upon users by the singularly > > brain damaged group of folks who call themselves freedesktop, > > I realise that's probably slightly tongue in cheek, but CLIPBOARD > long pre-dates the freedesktop effort AFAIK. Some of the same people > might be involved I guess. Only a little :-). I think my brain operates in a nearly perfect anti-freedesktop parallel universe. It seems like every time I find some incredibly annoying behavior being adopted by everyone I eventually trace it back to some document on freedesktop.org (that's why I use the fvwm window manager for instance - it proudly refuses to be freedesktop compliant :-). ^ permalink raw reply [flat|nested] 66+ messages in thread
* Re: Improving X selection? 2008-02-07 21:36 ` Tom Horsley @ 2008-02-07 21:40 ` David De La Harpe Golden 0 siblings, 0 replies; 66+ messages in thread From: David De La Harpe Golden @ 2008-02-07 21:40 UTC (permalink / raw) To: Tom Horsley; +Cc: Stephen J. Turnbull, Jan D., Stefan Monnier, rms, emacs-devel On 07/02/2008, Tom Horsley <tom.horsley@ccur.com> wrote: > Yuck. Perhaps I should have said it might as well only do PRIMARY, > if I tie my fingers in knots I can get CLIPBOARD :-). N.B. you don't do that every time, you turn on a "select to clipboard" flag with the ctrl-middlemouse menu, and then whenever you highlight it goes to clipboard instead of primary. it's also a resource selectToClipboard , so with appropriate configuration, you can get that behaviour without going into the menu. I've no idea when it was introduced into xterm though. ^ permalink raw reply [flat|nested] 66+ messages in thread
* Re: Improving X selection? 2008-02-07 21:01 ` Tom Horsley 2008-02-07 21:18 ` David De La Harpe Golden @ 2008-02-07 22:51 ` Stefan Monnier 1 sibling, 0 replies; 66+ messages in thread From: Stefan Monnier @ 2008-02-07 22:51 UTC (permalink / raw) To: Tom Horsley Cc: David De La Harpe Golden, Jan D., emacs-devel, Stephen J. Turnbull, rms >> For all three cases, the first question is "where does the text come from": >> No 3 should always use the CLIPBOARD then PRIMARY then kill ring. >> No 2 should use the CLIPBOARD only if x-select-enable-clipboard is set. >> No 1 is identical except it may also not check PRIMARY either. > This is, of course, totally a matter of opinion, and is the reason > the complication exists for those of us who have other opinions. I must say I do not understand. It seems your opinion is covered in the above. Except for the details of what happens where there's both a CLIPBOARD and a PRIMARY selection (and they're different, of course) which is neither mentioned nor ruled out. Stefan "Using ctwm" PS: For the rest I agree whole heartedly. Been through the pain of trying cut&paste and have it fail unexplicably (at least until I figured that one app uses CLIPBOARD and the other PRIMARY etc...). I also tend to agree with your rant about freedesktop. ^ permalink raw reply [flat|nested] 66+ messages in thread
[parent not found: <8e24944a0802071042u43d68f04pc8492ad8ce07aa18@mail.gmail.com>]
* Fwd: Improving X selection? [not found] ` <8e24944a0802071042u43d68f04pc8492ad8ce07aa18@mail.gmail.com> @ 2008-02-07 18:44 ` David De La Harpe Golden 0 siblings, 0 replies; 66+ messages in thread From: David De La Harpe Golden @ 2008-02-07 18:44 UTC (permalink / raw) To: emacs-devel; +Cc: Horsley, Tom, Jan D., rms, Stefan Monnier On 07/02/2008, Stephen J. Turnbull <stephen@xemacs.org> wrote: > (2) I expect it will be important to uptake that any behavior be > substantially mimicked on non-X platforms if at all possible. Indeed. That is why I indirected through two new interprogram- functions rather than using direct x-isms, so that other platforms (already supplying their own interprogram-cut/paste as noted elsewhere) could conceivably supply their own interprogram-highlight/lightins to have a stab at emulating the behaviour (dunno if it's possible to e.g. find and grab currently highlighted text from other apps with w32 or OSX API, but maybe it is via accessibility or services APIs or something - if it is, then a partial emulation of PRIMARY for incoming text would be possible) ^ permalink raw reply [flat|nested] 66+ messages in thread
* Re: Improving X selection? 2008-02-01 19:15 ` David De La Harpe Golden 2008-02-02 0:17 ` 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 1 sibling, 2 replies; 66+ messages in thread From: Richard Stallman @ 2008-02-03 16:18 UTC (permalink / raw) To: David De La Harpe Golden; +Cc: emacs-devel Attached patch introduces an interprogram-highlight-function and extends values of x-select-enable-clipboard / x-select-enable-primary in an (I think) useful manner*. The descriptions of the customizations may be overly verbose. Adding interprogram-highlight-function seems good to me Your proposed changes in x-win.el are very big; what is the purpose? Do they change the default behavior? Problem with select-active-regions is obvious: if you want it to work with both keyboard and mouse, it's not enough to reset the x11 selection when the mark is reset, it needs to be reset when the point is reset too, or the selection and active region will drift out of sync until the next mark reset. You have lost me already. Partly because you've skipped an important step -- you're talking about solving a problem without showing there is a problem. Why do you think there is a problem with select-active-regions? Can you present a test case and explain what behavior you think ought to be different? The hook post-point-motion would be very costly, so only a very powerful reason could convince me to install it. If you convince me there is a problem, I will look for other solutions; I certainly won't use this one. ^ permalink raw reply [flat|nested] 66+ messages in thread
* Re: Improving X selection? 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 1 sibling, 0 replies; 66+ messages in thread From: David De La Harpe Golden @ 2008-02-03 18:29 UTC (permalink / raw) To: rms; +Cc: emacs-devel On 03/02/2008, Richard Stallman <rms@gnu.org> wrote: > Adding interprogram-highlight-function seems good to me > > Your proposed changes in x-win.el are very big; Well, the delta is bloated partly because of my verbose docstrings for the extended customizations. Those should be cut down, I tend to write too much (I was eager to explain the ramifications of the different customizations. It also seemed to make sense to reuse the x-select-text code for x-select-text-for-highlight, so I made both into wrappers around one function, x-select-text-for-op parameterised by the "op" i.e. whether the function was being called for cutting or highlighting purposes by cut (x-select-text) or highlight (x-select-text-for-highlight) wrappers. That moved some code about, but just to avoid unnecessary redundancy. (And there's one more patch touching x-win.el to come, introducing the multiple-selections return thing that started the thread, and note that the already-forwarded mouse-behaviours-nice-with-select-active-regions.diff also affects x-win.el due to introduction of an interprogram-lightins-function that is to interprogram-highlight-function as interprogram-paste-function is to interprogram-cut-function) > what is the purpose? Well, the abstract purpose remains to make kill ring and active region interaction with the X11 clipboard and primary selections customizable to historic emacs defaults - and historic emacs possible customizations AND recent X11 conventions, without breaking backward compat. Regarding x-win.el in particular, the possible values of x-select-enable-primary and x-select-enable-clipboard were extended to allow more versatile specification of what selections are involved in what interprogram-cut/paste/highlight-function operations, rather than just all-or-nothing (and thereby somewhat problematic) "nil" and "t". > Do they change the default behavior? Depends entirely on defaults chosen for customize variables x-select-enable-primary and x-select-enable-clipboard (and x-select-enable-cutbuffer, but, well, does anyone use cut buffers?) The patch picked new defaults, but only out of last-minute thoughtlessness on my part (my local tree defaults are the settings I want to get working): The existing default behaviour (and existing customisation possibilities to default behaviour) is still possible, and backward-compat is peserved, some complexity stems from me being paranoid about keeping it all possible if anything. > Why do you think there is a problem with select-active-regions? > Can you present a test case and explain what behavior you think > ought to be different? > Okay, I'll try: with transient mark mode on, select-active-regions on. a buffer with a bunch of text in. Set mark (C-SPC) somewhere, Move point somewhere else (with cursor keys). The active region between the mark and point is visible on screen as a highlight. Problem: The primary X11 selection is not updated to reflect the just-reshaped active region, despite select-active-regions being on. Why is this a problem? Because the highlight on the screen will stop matching the primary X11 selection, so users will get something unexpected or nothing when they try to middle-click transfer the emacs highlight into other applications. Why does this problem happen? Because the mark doesn't change if you only move the point, and if the mark doesn't change, the select-active-regions callout to set the X11 selection in set-mark doesn't run. How did I "fix" it (apart from "badly")? Check if the region is active on every point move as well as every mark move, and set the X11 selection then too (when select-active-regions is set). > The hook post-point-motion would be very costly, > so only a very powerful reason could convince me to install it. Well, for select-active-regions to work (work: keep active region and X11 selection synchronised), I didn't see any good way around calling something whenever the active region changes shape. And when does the active region change shape? When the point or mark moves. Without updating when the point moves, it's only doing 1/2 the job. ^ permalink raw reply [flat|nested] 66+ messages in thread
* Re: Improving X selection? 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 1 sibling, 1 reply; 66+ messages in thread From: David De La Harpe Golden @ 2008-02-05 5:58 UTC (permalink / raw) To: rms; +Cc: emacs-devel [-- Attachment #1: Type: text/plain, Size: 609 bytes --] On 03/02/2008, Richard Stallman <rms@gnu.org> wrote: > If you convince me there is a problem, I will look for other > solutions; I certainly won't use this one. > Other solutions - fixing select-active-regions with an idle timer that polls the region for changes? Here's a (standalone, i.e. against CVS, not incremental to other patches) attempt with run-with-idle-timer. Seems to work okay, though is probably not incredibly efficient (has got to be better than doing something every single point move though). [Because I put it in simple.el and it uses timer, had to change load order in loadup.el...] [-- Warning: decoded text below may be mangled, UTF-8 assumed --] [-- Attachment #2: select-active-regions-when-idle.diff --] [-- Type: text/x-diff; name=select-active-regions-when-idle.diff, Size: 3469 bytes --] Index: lisp/simple.el =================================================================== RCS file: /sources/emacs/emacs/lisp/simple.el,v retrieving revision 1.899 diff -u -r1.899 simple.el --- lisp/simple.el 1 Feb 2008 16:01:05 -0000 1.899 +++ lisp/simple.el 5 Feb 2008 05:49:19 -0000 @@ -3323,11 +3323,55 @@ (setq mark-active nil) (run-hooks 'deactivate-mark-hook)))) + +(defun set-select-active-regions (opt val) + (setq select-active-regions val) + (setq select-active-regions-last-region nil) + (if val + (progn + (funcall 'cancel-function-timers + 'maybe-select-for-select-active-regions) + (run-with-idle-timer + 0 t'maybe-select-for-select-active-regions)) + (funcall 'cancel-function-timers + 'maybe-select-for-select-active-regions))) + + (defcustom select-active-regions nil "If non-nil, an active region automatically becomes the window selection." :type 'boolean :group 'killing - :version "23.1") + :version "23.1" + :risky t + :set 'set-select-active-regions) + + + +(defvar select-active-regions-last-region nil + "record of last propagated region for comparison.") + +(defun maybe-select-for-select-active-regions () + "Implements `select-active-regions'. Called by timer +`select-active-regions-timer' and `set-mark'" + (and select-active-regions + (region-active-p) + (let ((current-region-text + (buffer-substring (region-beginning) (region-end)))) + (if (or (null select-active-regions-last-region) + (not (string= select-active-regions-last-region + current-region-text))) + (if (or (null current-region-text) + (string= "" current-region-text)) + ;; don't propagate if this region is empty, but this + ;; region being empty means future nonempty regions + ;; need repropagation + (setq select-active-regions-last-region nil) + ;; this should be a call to interprogram-highlight-function + ;; if/when that is introduced. + (x-set-selection nil current-region-text) + (setq select-active-regions-last-region + current-region-text)))))) + (defun set-mark (pos) "Set this buffer's mark to POS. Don't use this function! @@ -3351,8 +3395,9 @@ (setq mark-active t) (run-hooks 'activate-mark-hook) (and select-active-regions - (x-set-selection - nil (buffer-substring (region-beginning) (region-end)))) + ;; force repropagate if mark is reset + (progn (setq select-active-regions-last-region nil) + (maybe-select-for-select-active-regions))) (set-marker (mark-marker) pos (current-buffer))) ;; Normally we never clear mark-active except in Transient Mark mode. ;; But when we actually clear out the mark value too, Index: lisp/loadup.el =================================================================== RCS file: /sources/emacs/emacs/lisp/loadup.el,v retrieving revision 1.160 diff -u -r1.160 loadup.el --- lisp/loadup.el 1 Feb 2008 22:43:10 -0000 1.160 +++ lisp/loadup.el 5 Feb 2008 05:49:19 -0000 @@ -82,6 +82,8 @@ (message "%s" (garbage-collect)) (load "loaddefs.el") ;Don't get confused if someone compiled this by mistake. (message "%s" (garbage-collect)) + +(load "emacs-lisp/timer") ; select-active-region in simple.el needs timer. (load "simple") (load "help") @@ -145,7 +147,6 @@ (and (boundp 'x-toolkit-scroll-bars) (load "scroll-bar")) (load "select"))) -(load "emacs-lisp/timer") (load "isearch") (load "rfn-eshadow") ^ permalink raw reply [flat|nested] 66+ messages in thread
* Re: Improving X selection? 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 0 siblings, 1 reply; 66+ messages in thread From: Miles Bader @ 2008-02-05 6:23 UTC (permalink / raw) To: David De La Harpe Golden; +Cc: rms, emacs-devel "David De La Harpe Golden" <david.delaharpe.golden@gmail.com> writes: > Other solutions - fixing select-active-regions with an idle timer that > polls the region for changes? Why don't you only keep the timer when the region is actually active (rather rarely in typical usage I think)? It's certainly not a feature worth slowing down Emacs when it's not being used... -Miles -- `There are more things in heaven and earth, Horatio, Than are dreamt of in your philosophy.' ^ permalink raw reply [flat|nested] 66+ messages in thread
* Re: Improving X selection? 2008-02-05 6:23 ` Miles Bader @ 2008-02-05 6:56 ` David De La Harpe Golden 0 siblings, 0 replies; 66+ messages in thread From: David De La Harpe Golden @ 2008-02-05 6:56 UTC (permalink / raw) To: Miles Bader; +Cc: rms, emacs-devel [-- Attachment #1: Type: text/plain, Size: 411 bytes --] On 05/02/2008, Miles Bader <miles.bader@necel.com> wrote: > "David De La Harpe Golden" <david.delaharpe.golden@gmail.com> writes: > > Other solutions - fixing select-active-regions with an idle timer that > > polls the region for changes? > > Why don't you only keep the timer when the region is actually active > (rather rarely in typical usage I think)? > Geez. That would be far too sensible.... attached. [-- Warning: decoded text below may be mangled, UTF-8 assumed --] [-- Attachment #2: select-active-regions-when-idle2.diff --] [-- Type: text/x-diff; name=select-active-regions-when-idle2.diff, Size: 3546 bytes --] Index: lisp/simple.el =================================================================== RCS file: /sources/emacs/emacs/lisp/simple.el,v retrieving revision 1.899 diff -u -r1.899 simple.el --- lisp/simple.el 1 Feb 2008 16:01:05 -0000 1.899 +++ lisp/simple.el 5 Feb 2008 06:53:10 -0000 @@ -3316,6 +3316,7 @@ "Deactivate the mark by setting `mark-active' to nil. \(That makes a difference only in Transient Mark mode.) Also runs the hook `deactivate-mark-hook'." + (cancel-function-timers 'maybe-select-for-select-active-regions) (cond ((eq transient-mark-mode 'lambda) (setq transient-mark-mode nil)) @@ -3323,11 +3324,39 @@ (setq mark-active nil) (run-hooks 'deactivate-mark-hook)))) + (defcustom select-active-regions nil "If non-nil, an active region automatically becomes the window selection." :type 'boolean :group 'killing - :version "23.1") + :version "23.1" + :risky t) + +(defvar select-active-regions-last-region nil + "record of last propagated region for comparison.") + +(defun maybe-select-for-select-active-regions () + "Implements `select-active-regions'. Called by timer +`select-active-regions-timer' and `set-mark'" + (and select-active-regions + (region-active-p) + (let ((current-region-text + (buffer-substring (region-beginning) (region-end)))) + (if (or (null select-active-regions-last-region) + (not (string= select-active-regions-last-region + current-region-text))) + (if (or (null current-region-text) + (string= "" current-region-text)) + ;; don't propagate if this region is empty, but this + ;; region being empty means future nonempty regions + ;; need repropagation + (setq select-active-regions-last-region nil) + ;; this should be a call to interprogram-highlight-function + ;; if/when that is introduced. + (x-set-selection nil current-region-text) + (setq select-active-regions-last-region + current-region-text)))))) + (defun set-mark (pos) "Set this buffer's mark to POS. Don't use this function! @@ -3350,9 +3379,13 @@ (progn (setq mark-active t) (run-hooks 'activate-mark-hook) - (and select-active-regions - (x-set-selection - nil (buffer-substring (region-beginning) (region-end)))) + (when select-active-regions + (cancel-function-timers 'maybe-select-for-select-active-regions) + (run-with-idle-timer + 0 t 'maybe-select-for-select-active-regions) + ;; force repropagate if mark is reset + (progn (setq select-active-regions-last-region nil) + (maybe-select-for-select-active-regions))) (set-marker (mark-marker) pos (current-buffer))) ;; Normally we never clear mark-active except in Transient Mark mode. ;; But when we actually clear out the mark value too, Index: lisp/loadup.el =================================================================== RCS file: /sources/emacs/emacs/lisp/loadup.el,v retrieving revision 1.160 diff -u -r1.160 loadup.el --- lisp/loadup.el 1 Feb 2008 22:43:10 -0000 1.160 +++ lisp/loadup.el 5 Feb 2008 06:53:11 -0000 @@ -82,6 +82,8 @@ (message "%s" (garbage-collect)) (load "loaddefs.el") ;Don't get confused if someone compiled this by mistake. (message "%s" (garbage-collect)) + +(load "emacs-lisp/timer") ; select-active-region in simple.el needs timer. (load "simple") (load "help") @@ -145,7 +147,6 @@ (and (boundp 'x-toolkit-scroll-bars) (load "scroll-bar")) (load "select"))) -(load "emacs-lisp/timer") (load "isearch") (load "rfn-eshadow") ^ permalink raw reply [flat|nested] 66+ messages in thread
* Re: Improving X selection? 2008-01-29 0:59 ` David De La Harpe Golden 2008-02-01 19:15 ` David De La Harpe Golden @ 2008-02-03 16:18 ` Richard Stallman 1 sibling, 0 replies; 66+ messages in thread From: Richard Stallman @ 2008-02-03 16:18 UTC (permalink / raw) To: David De La Harpe Golden; +Cc: emacs-devel Okay, more nearly on same page now, see the "select-active-regions" you introduced equivalent to the hook*. So I'll stop calling it the hook now. Anyway, it's not happening in some circumstances. It has been a long time since I thought about your patch, and I don't remember all the details of the issue. What exactly is "not happening", and what are the circumstances? Can you specify a test case? * Maybe might want an interprogram-highlight-function to indirect through like interprogram-[cut|paste]-function, rather than embedding a direct call to x-set-selection, which I presume doesn't work on non-X11 ? I am lost here. There is no such thing as interprogram-highlight-function, so perhaps your proposal is to add it, but I can't understand what you want it to do, or why. ^ permalink raw reply [flat|nested] 66+ messages in thread
end of thread, other threads:[~2008-02-17 3:55 UTC | newest] Thread overview: 66+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 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 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
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).