Change `select-active-region' mechanics.
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.
This commit is contained in:
parent
d064e6a60d
commit
9852377f78
9 changed files with 132 additions and 56 deletions
5
etc/NEWS
5
etc/NEWS
|
@ -192,7 +192,10 @@ The way Emacs interacts with the clipboard and primary selection, by
|
|||
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.
|
||||
|
||||
|
|
|
@ -1,3 +1,18 @@
|
|||
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.
|
||||
|
|
|
@ -197,6 +197,11 @@ Leaving \"Default\" unchecked is equivalent with specifying a default of
|
|||
(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")))
|
||||
|
|
|
@ -697,9 +697,6 @@ This should be bound to a mouse drag event."
|
|||
(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)))
|
||||
|
@ -905,10 +902,6 @@ DO-MOUSE-DRAG-REGION-POST-PROCESS should only be used by
|
|||
`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
|
||||
|
@ -955,10 +948,7 @@ DO-MOUSE-DRAG-REGION-POST-PROCESS should only be used by
|
|||
(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)))
|
||||
|
@ -1017,23 +1007,16 @@ DO-MOUSE-DRAG-REGION-POST-PROCESS should only be used by
|
|||
|
||||
;; 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
|
||||
|
@ -1251,9 +1234,7 @@ 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.
|
||||
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)
|
||||
|
|
|
@ -3666,29 +3666,27 @@ a mistake; see the documentation of `set-mark'."
|
|||
(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)
|
||||
|
@ -3706,14 +3704,7 @@ This function also runs `deactivate-mark-hook'."
|
|||
(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!
|
||||
|
@ -3736,7 +3727,6 @@ store it in a Lisp variable. Example:
|
|||
(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
|
||||
|
@ -3820,7 +3810,6 @@ Display `Mark set' unless the optional second arg NOMSG is non-nil."
|
|||
(push-mark nil nomsg t)
|
||||
(setq mark-active t)
|
||||
(run-hooks 'activate-mark-hook)
|
||||
(select-active-region)
|
||||
(unless nomsg
|
||||
(message "Mark activated")))))
|
||||
|
||||
|
@ -4008,11 +3997,8 @@ Otherwise, if the region has been activated temporarily,
|
|||
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)
|
||||
|
@ -5576,7 +5562,10 @@ it skips the contents of comments that end before point."
|
|||
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)
|
||||
|
|
|
@ -1,3 +1,16 @@
|
|||
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):
|
||||
|
|
17
src/insdel.c
17
src/insdel.c
|
@ -74,6 +74,8 @@ Lisp_Object combine_after_change_buffer;
|
|||
|
||||
Lisp_Object Qinhibit_modification_hooks;
|
||||
|
||||
extern Lisp_Object Vselect_active_regions, Vsaved_region_selection;
|
||||
|
||||
|
||||
/* Check all markers in the current buffer, looking for something invalid. */
|
||||
|
||||
|
@ -2047,6 +2049,21 @@ prepare_to_modify_buffer (EMACS_INT start, EMACS_INT end,
|
|||
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)
|
||||
|
|
|
@ -361,6 +361,15 @@ Lisp_Object Vlast_event_frame;
|
|||
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;
|
||||
|
@ -1781,11 +1790,26 @@ command_loop_1 (void)
|
|||
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:
|
||||
|
@ -11682,6 +11706,13 @@ syms_of_keyboard (void)
|
|||
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");
|
||||
|
@ -12289,6 +12320,28 @@ Help functions bind this to allow help on disabled menu items
|
|||
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);
|
||||
|
|
|
@ -2916,7 +2916,7 @@ A value of 0 means wait as long as necessary. This is initialized from the
|
|||
\"*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);
|
||||
|
|
Loading…
Add table
Reference in a new issue