Save region text prior to buffer modification.
Set window selection lazily, during `deactivate-mark' or after each
command when the region is temporarily active.
* lisp/cus-start.el: Add custom declaration for select-active-regions.
* lisp/mouse.el (mouse-drag-track): Remove hacks to deal with old
select-active-regions implementation.
(mouse-yank-at-click): Doc fix.
* lisp/simple.el (select-active-regions): Move to keyboard.c.
(deactivate-mark): Used saved-region-selection.
(select-active-region): Function removed.
(activate-mark, set-mark, push-mark-command)
(handle-shift-selection): Don't call it.
(keyboard-quit): Avoid adding the region to the window selection.
* src/insdel.c (prepare_to_modify_buffer): Save active region text to
Vsaved_region_selection.
* src/keyboard.c (Vselect_active_regions): Move from simple.el.
(Vsaved_region_selection, Qx_set_selection, QPRIMARY, Qlazy): New
vars.
(command_loop_1): Set window selection prior to deactivating the
mark.
* src/xselect.c (QPRIMARY): Move to keyboard.c.
default, is now similar to other X applications. In particular, kill
and yank use the clipboard, in addition to the primary selection.
-*** `select-active-regions' now defaults to t.
+*** `select-active-regions' now defaults to `lazy'.
+This means that any active region made with shift-selection or mouse
+dragging, or acted on by Emacs (e.g. with M-w or C-w), is
+automatically added to the primary window selection.
*** `x-select-enable-clipboard' now defaults to t.
+2010-08-07 Chong Yidong <cyd@stupidchicken.com>
+
+ * simple.el (select-active-regions): Move to keyboard.c.
+ (deactivate-mark): Used saved-region-selection.
+ (select-active-region): Function removed.
+ (activate-mark, set-mark, push-mark-command)
+ (handle-shift-selection): Don't call it.
+ (keyboard-quit): Avoid adding the region to the window selection.
+
+ * mouse.el (mouse-drag-track): Remove hacks to deal with old
+ select-active-regions implementation.
+ (mouse-yank-at-click): Doc fix.
+
+ * cus-start.el: Add custom declaration for select-active-regions.
+
2010-08-07 Eli Zaretskii <eliz@gnu.org>
* simple.el (delete-forward-char): Doc fix.
(help-char keyboard character)
(help-event-list keyboard (repeat (sexp :format "%v")))
(menu-prompting menu boolean)
+ (select-active-regions killing
+ (choice (const :tag "lazy" lazy)
+ (const :tag "always" t)
+ (const :tag "off" nil))
+ "24.1")
(suggest-key-bindings keyboard (choice (const :tag "off" nil)
(integer :tag "time" 2)
(other :tag "on")))
(window-system)
(sit-for 1))
(push-mark)
- ;; If `select-active-regions' is non-nil, `set-mark' sets the
- ;; primary selection to the buffer's region, overriding the role
- ;; of `copy-region-as-kill'; that's why we did the copy first.
(set-mark (point))
(if (numberp end) (goto-char end))
(mouse-set-region-1)))
`mouse-drag-region'."
(mouse-minibuffer-check start-event)
(setq mouse-selection-click-count-buffer (current-buffer))
- ;; We must call deactivate-mark before repositioning point.
- ;; Otherwise, for `select-active-regions' non-nil, we get the wrong
- ;; selection if the user drags a region, clicks elsewhere to
- ;; reposition point, then middle-clicks to paste the selection.
(deactivate-mark)
(let* ((original-window (selected-window))
;; We've recorded what we needed from the current buffer and
(if (eq transient-mark-mode 'lambda)
'(only)
(cons 'only transient-mark-mode)))
- (let ((range (mouse-start-end start-point start-point click-count))
- ;; Prevent `push-mark' from clobbering the primary selection
- ;; if the user clicks without dragging.
- (select-active-regions nil))
+ (let ((range (mouse-start-end start-point start-point click-count)))
(goto-char (nth 0 range))
(push-mark nil t t)
(goto-char (nth 1 range)))
;; If point has moved, finish the drag.
(let* (last-command this-command)
- ;; Copy the region so that `select-active-regions' can
- ;; override `copy-region-as-kill'.
(and mouse-drag-copy-region
do-mouse-drag-region-post-process
(let (deactivate-mark)
- (copy-region-as-kill (mark) (point))))
- ;; For `select-active-regions' non-nil, ensure that
- ;; further alterations of the region (e.g. via
- ;; shift-selection) continue to update PRIMARY.
- (select-active-region))
+ (copy-region-as-kill (mark) (point)))))
;; If point hasn't moved, run the binding of the
;; terminating up-event.
(if do-multi-click
(goto-char start-point)
- (let (select-active-regions)
- (deactivate-mark)))
+ (deactivate-mark))
(when (and (functionp fun)
(= start-hscroll (window-hscroll start-window))
;; Don't run the up-event handler if the window
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.
-If `select-active-regions' is non-nil, the mark is deactivated
-before inserting the text."
+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)
(marker-position (mark-marker))
(signal 'mark-inactive nil)))
-(defcustom select-active-regions t
- "If non-nil, an active region automatically becomes the window selection."
- :type 'boolean
- :group 'killing
- :version "24.1")
-
(declare-function x-selection-owner-p "xselect.c" (&optional selection))
-;; Many places set mark-active directly, and several of them failed to also
-;; run deactivate-mark-hook. This shorthand should simplify.
(defsubst deactivate-mark (&optional force)
"Deactivate the mark by setting `mark-active' to nil.
Unless FORCE is non-nil, this function does nothing if Transient
Mark mode is disabled.
This function also runs `deactivate-mark-hook'."
(when (or transient-mark-mode force)
- ;; Copy the latest region into the primary selection, if desired.
- (and select-active-regions
- mark-active
- (display-selections-p)
- (x-selection-owner-p 'PRIMARY)
- (x-set-selection 'PRIMARY (buffer-substring-no-properties
- (region-beginning) (region-end))))
+ (when (and select-active-regions
+ (region-active-p)
+ (display-selections-p))
+ ;; The var `saved-region-selection', if non-nil, is the text in
+ ;; the region prior to the last command modifying the buffer.
+ ;; Set the selection to that, or to the current region.
+ (cond (saved-region-selection
+ (x-set-selection 'PRIMARY saved-region-selection)
+ (setq saved-region-selection nil))
+ ((/= (region-beginning) (region-end))
+ (x-set-selection 'PRIMARY
+ (buffer-substring-no-properties
+ (point) (mark))))))
(if (and (null force)
(or (eq transient-mark-mode 'lambda)
(and (eq (car-safe transient-mark-mode) 'only)
(when (mark t)
(setq mark-active t)
(unless transient-mark-mode
- (setq transient-mark-mode 'lambda))
- (select-active-region)))
-
-(defsubst select-active-region ()
- "Set the PRIMARY X selection if `select-active-regions' is non-nil."
- (and select-active-regions
- (display-selections-p)
- (x-set-selection 'PRIMARY (current-buffer))))
+ (setq transient-mark-mode 'lambda))))
(defun set-mark (pos)
"Set this buffer's mark to POS. Don't use this function!
(progn
(setq mark-active t)
(run-hooks 'activate-mark-hook)
- (select-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
(push-mark nil nomsg t)
(setq mark-active t)
(run-hooks 'activate-mark-hook)
- (select-active-region)
(unless nomsg
(message "Mark activated")))))
deactivate it, and restore the variable `transient-mark-mode' to
its earlier value."
(cond ((and shift-select-mode this-command-keys-shift-translated)
- (if (and mark-active
- (eq (car-safe transient-mark-mode) 'only))
- ;; Another program may have grabbed the selection; make
- ;; sure we get it back now.
- (select-active-region)
+ (unless (and mark-active
+ (eq (car-safe transient-mark-mode) 'only))
(setq transient-mark-mode
(cons 'only
(unless (eq transient-mark-mode 'lambda)
During execution of Lisp code, this character causes a quit directly.
At top-level, as an editor command, this simply beeps."
(interactive)
- (deactivate-mark)
+ ;; Avoid adding the region to the window selection.
+ (setq saved-region-selection nil)
+ (let (select-active-regions)
+ (deactivate-mark))
(if (fboundp 'kmacro-keyboard-quit)
(kmacro-keyboard-quit))
(setq defining-kbd-macro nil)
+2010-08-07 Chong Yidong <cyd@stupidchicken.com>
+
+ * insdel.c (prepare_to_modify_buffer): Save active region text to
+ Vsaved_region_selection.
+
+ * xselect.c (QPRIMARY): Move to keyboard.c.
+
+ * keyboard.c (Vselect_active_regions): Move from simple.el.
+ (Vsaved_region_selection, Qx_set_selection, QPRIMARY, Qlazy): New
+ vars.
+ (command_loop_1): Set window selection prior to deactivating the
+ mark.
+
2010-08-07 Juanma Barranquero <lekktu@gmail.com>
* alloc.c (lisp_malloc):
Lisp_Object Qinhibit_modification_hooks;
+extern Lisp_Object Vselect_active_regions, Vsaved_region_selection;
+
\f
/* Check all markers in the current buffer, looking for something invalid. */
base_buffer->filename);
#endif /* not CLASH_DETECTION */
+ /* If `select-active-regions' is non-nil, save the region text. */
+ if (!NILP (Vselect_active_regions)
+ && !NILP (current_buffer->mark_active)
+ && !NILP (Vtransient_mark_mode)
+ && NILP (Vsaved_region_selection))
+ {
+ Lisp_Object b = Fmarker_position (current_buffer->mark);
+ Lisp_Object e = make_number (PT);
+ if (NILP (Fequal (b, e)))
+ {
+ validate_region (&b, &e);
+ Vsaved_region_selection = make_buffer_string (XINT (b), XINT (e), 0);
+ }
+ }
+
signal_before_change (start, end, preserve_ptr);
if (current_buffer->newline_cache)
X Windows wants this for selection ownership. */
unsigned long last_event_timestamp;
+/* If non-nil, active regions automatically become the window selection. */
+Lisp_Object Vselect_active_regions;
+
+/* The text in the active region prior to modifying the buffer.
+ Used by the `select-active-regions' feature. */
+Lisp_Object Vsaved_region_selection;
+
+Lisp_Object Qx_set_selection, QPRIMARY, Qlazy;
+
Lisp_Object Qself_insert_command;
Lisp_Object Qforward_char;
Lisp_Object Qbackward_char;
Vtransient_mark_mode = Qnil;
else if (EQ (Vtransient_mark_mode, Qonly))
Vtransient_mark_mode = Qidentity;
+ else if (EQ (Vselect_active_regions, Qlazy)
+ ? EQ (CAR_SAFE (Vtransient_mark_mode), Qonly)
+ : (!NILP (Vselect_active_regions)
+ && !NILP (Vtransient_mark_mode)))
+ {
+ /* Set window selection. If `select-active-regions' is
+ `lazy', only do it for temporarily active regions. */
+ Lisp_Object beg = Fmarker_position (current_buffer->mark);
+ Lisp_Object end = make_number (PT);
+ validate_region (&beg, &end);
+ call2 (Qx_set_selection, QPRIMARY,
+ make_buffer_string (XINT (beg), XINT (end), 0));
+ }
if (!NILP (Vdeactivate_mark))
call0 (Qdeactivate_mark);
else if (current_buffer != prev_buffer || MODIFF != prev_modiff)
call1 (Vrun_hooks, intern ("activate-mark-hook"));
+
+ Vsaved_region_selection = Qnil;
}
finalize:
Qinput_method_function = intern_c_string ("input-method-function");
staticpro (&Qinput_method_function);
+ Qx_set_selection = intern_c_string ("x-set-selection");
+ staticpro (&Qx_set_selection);
+ QPRIMARY = intern_c_string ("PRIMARY");
+ staticpro (&QPRIMARY);
+ Qlazy = intern_c_string ("lazy");
+ staticpro (&Qlazy);
+
Qinput_method_exit_on_first_char = intern_c_string ("input-method-exit-on-first-char");
staticpro (&Qinput_method_exit_on_first_char);
Qinput_method_use_echo_area = intern_c_string ("input-method-use-echo-area");
and tool-bar buttons. */);
Venable_disabled_menus_and_buttons = Qnil;
+ DEFVAR_LISP ("select-active-regions",
+ &Vselect_active_regions,
+ doc: /* If non-nil, an active region automatically becomes the window selection.
+This takes effect only when Transient Mark mode is enabled.
+
+If the value is `lazy', Emacs only sets the window selection during
+`deactivate-mark'; unless the region is temporarily active
+(e.g. mouse-drags or shift-selection), in which case it sets the
+window selection after each command.
+
+For other non-nil value, Emacs sets the window selection after every
+command. */);
+ Vselect_active_regions = Qlazy;
+
+ DEFVAR_LISP ("saved-region-selection",
+ &Vsaved_region_selection,
+ doc: /* Contents of active region prior to buffer modification.
+If `select-active-regions' is non-nil, Emacs sets this to the
+text in the region before modifying the buffer. The next
+`deactivate-mark' call uses this to set the window selection. */);
+ Vsaved_region_selection = Qnil;
+
/* Create the initial keyboard. */
initial_kboard = (KBOARD *) xmalloc (sizeof (KBOARD));
init_kboard (initial_kboard);
\"*selectionTimeout\" resource. */);
x_selection_timeout = 0;
- QPRIMARY = intern_c_string ("PRIMARY"); staticpro (&QPRIMARY);
+ /* QPRIMARY is defined in keyboard.c. */
QSECONDARY = intern_c_string ("SECONDARY"); staticpro (&QSECONDARY);
QSTRING = intern_c_string ("STRING"); staticpro (&QSTRING);
QINTEGER = intern_c_string ("INTEGER"); staticpro (&QINTEGER);