X-Git-Url: https://code.delx.au/gnu-emacs/blobdiff_plain/e0da2cddda8d2244be17fe33fd3130af8c8041c8..b336bfcdf39f1e4d35bff4a7bd01d3b4bca8f516:/lisp/mouse-sel.el diff --git a/lisp/mouse-sel.el b/lisp/mouse-sel.el index b6f4558f28..d7f4c9bd22 100644 --- a/lisp/mouse-sel.el +++ b/lisp/mouse-sel.el @@ -1,16 +1,17 @@ ;;; mouse-sel.el --- multi-click selection support for Emacs 19 -;; Copyright (C) 1993,1994,1995,2001,2002 Free Software Foundation, Inc. +;; Copyright (C) 1993, 1994, 1995, 2001, 2002, 2003, 2004, +;; 2005, 2006, 2007, 2008, 2009, 2010 Free Software Foundation, Inc. ;; Author: Mike Williams ;; Keywords: mouse ;; This file is part of GNU Emacs. -;; GNU Emacs is free software; you can redistribute it and/or modify +;; GNU Emacs is free software: you can redistribute it and/or modify ;; it under the terms of the GNU General Public License as published by -;; the Free Software Foundation; either version 2, or (at your option) -;; any later version. +;; the Free Software Foundation, either version 3 of the License, or +;; (at your option) any later version. ;; GNU Emacs is distributed in the hope that it will be useful, ;; but WITHOUT ANY WARRANTY; without even the implied warranty of @@ -18,9 +19,7 @@ ;; GNU General Public License for more details. ;; You should have received a copy of the GNU General Public License -;; along with GNU Emacs; see the file COPYING. If not, write to the -;; Free Software Foundation, Inc., 59 Temple Place - Suite 330, -;; Boston, MA 02111-1307, USA. +;; along with GNU Emacs. If not, see . ;;; Commentary: @@ -114,14 +113,14 @@ ;; * I like to leave point at the end of the region nearest to where the ;; mouse was, even though this makes region highlighting mis-leading (the ;; cursor makes it look like one extra character is selected). You can -;; disable this behaviour with: +;; disable this behavior with: ;; ;; (setq mouse-sel-leave-point-near-mouse nil) ;; ;; * By default, mouse-select cycles the click count after 4 clicks. That ;; is, clicking mouse-1 five times has the same effect as clicking it ;; once, clicking six times has the same effect as clicking twice, etc. -;; Disable this behaviour with: +;; Disable this behavior with: ;; ;; (setq mouse-sel-cycle-clicks nil) ;; @@ -151,7 +150,7 @@ :group 'mouse) (defcustom mouse-sel-leave-point-near-mouse t - "*Leave point near last mouse position. + "Leave point near last mouse position. If non-nil, \\[mouse-select] and \\[mouse-extend] will leave point at the end of the region nearest to where the mouse last was. If nil, point will always be placed at the beginning of the region." @@ -159,12 +158,12 @@ If nil, point will always be placed at the beginning of the region." :group 'mouse-sel) (defcustom mouse-sel-cycle-clicks t - "*If non-nil, \\[mouse-select] cycles the click-counts after 4 clicks." + "If non-nil, \\[mouse-select] cycles the click-counts after 4 clicks." :type 'boolean :group 'mouse-sel) (defcustom mouse-sel-default-bindings t - "*Control mouse bindings." + "Control mouse bindings." :type '(choice (const :tag "none" nil) (const :tag "cut and paste" interprogram-cut-paste) (other :tag "default bindings" t)) @@ -243,7 +242,11 @@ primary selection and region." :group 'mouse-sel (if mouse-sel-mode (progn - (add-hook 'x-lost-selection-hooks 'mouse-sel-lost-selection-hook) + ;; If mouse-2 has never been done by the user, initialize the + ;; `event-kind' property to ensure that `follow-link' clicks + ;; are interpreted correctly. + (put 'mouse-2 'event-kind 'mouse-click) + (add-hook 'x-lost-selection-functions 'mouse-sel-lost-selection-hook) (when mouse-sel-default-bindings ;; Save original bindings and replace them with new ones. (setq mouse-sel-original-bindings @@ -263,7 +266,7 @@ primary selection and region." interprogram-paste-function nil)))) ;; Restore original bindings - (remove-hook 'x-lost-selection-hooks 'mouse-sel-lost-selection-hook) + (remove-hook 'x-lost-selection-functions 'mouse-sel-lost-selection-hook) (dolist (binding mouse-sel-original-bindings) (global-set-key (car binding) (cdr binding))) ;; Restore the old values of these variables, @@ -302,6 +305,8 @@ where SELECTION-NAME = name of selection SELECTION-THING-SYMBOL = name of variable where the current selection type for this selection should be stored.") +(declare-function x-select-text "term/x-win" (text &optional push)) + (defvar mouse-sel-set-selection-function (if (eq mouse-sel-default-bindings 'interprogram-cut-paste) 'x-set-selection @@ -318,6 +323,8 @@ Called with two arguments: This sets the selection as well as the cut buffer for the older applications, unless `mouse-sel-default-bindings' is `interprogram-cut-paste'.") +(declare-function x-cut-buffer-or-selection-value "term/x-win" ()) + (defvar mouse-sel-get-selection-function (lambda (selection) (if (eq selection 'PRIMARY) @@ -464,10 +471,12 @@ Clicking mouse-1 or mouse-3 kills the selected text. This should be bound to a down-mouse event." (interactive "@e") - (let (direction) + (let (select) (unwind-protect - (setq direction (mouse-select-internal 'PRIMARY event)) - (mouse-sel-primary-to-region direction)))) + (setq select (mouse-select-internal 'PRIMARY event)) + (if (and select (listp select)) + (push (cons 'mouse-2 (cdr event)) unread-command-events) + (mouse-sel-primary-to-region select))))) (defun mouse-select-secondary (event) "Set secondary selection using the mouse. @@ -486,7 +495,14 @@ This should be bound to a down-mouse event." (mouse-select-internal 'SECONDARY event)) (defun mouse-select-internal (selection event) - "Set SELECTION using the mouse." + "Set SELECTION using the mouse, with EVENT as the initial down-event. +Normally, this returns the direction in which the selection was +made: a value of 1 indicates that the mouse was dragged +left-to-right, otherwise it was dragged right-to-left. + +However, if `mouse-1-click-follows-link' is non-nil and the +subsequent mouse events specify following a link, this returns +the final mouse-event. In that case, the selection is not set." (mouse-sel-eval-at-event-end event (let ((thing-symbol (mouse-sel-selection-thing selection)) (overlay (mouse-sel-selection-overlay selection))) @@ -500,7 +516,8 @@ This should be bound to a down-mouse event." (car object-bounds) (cdr object-bounds) (current-buffer))) (move-overlay overlay (point) (point) (current-buffer))))) - (mouse-extend-internal selection))) + (catch 'follow-link + (mouse-extend-internal selection event t)))) ;;=== Extend ============================================================== @@ -522,11 +539,12 @@ This should be bound to a down-mouse event." (save-window-excursion (mouse-extend-internal 'SECONDARY event))) -(defun mouse-extend-internal (selection &optional initial-event) +(defun mouse-extend-internal (selection &optional initial-event no-process) "Extend specified SELECTION using the mouse. Track mouse-motion events, adjusting the SELECTION appropriately. -Optional argument INITIAL-EVENT specifies an initial down-mouse event to -process. +Optional argument INITIAL-EVENT specifies an initial down-mouse event. +Optional argument NO-PROCESS means not to process the initial +event. See documentation for mouse-select-internal for more details." (mouse-sel-eval-at-event-end initial-event @@ -563,7 +581,8 @@ See documentation for mouse-select-internal for more details." ;; Handle dragging (track-mouse - (while (if initial-event ; Use initial event + (while (if (and initial-event (not no-process)) + ;; Use initial event (prog1 (setq event initial-event) (setq initial-event nil)) @@ -642,6 +661,10 @@ See documentation for mouse-select-internal for more details." ))) ; end track-mouse + ;; Detect follow-link events + (when (mouse-sel-follow-link-p initial-event event) + (throw 'follow-link event)) + ;; Finish up after dragging (let ((overlay-start (overlay-start overlay)) (overlay-end (overlay-end overlay))) @@ -678,6 +701,25 @@ See documentation for mouse-select-internal for more details." )))) +(defun mouse-sel-follow-link-p (initial final) + "Return t if we should follow a link, given INITIAL and FINAL mouse events. +See `mouse-1-click-follows-link' for details. Currently, Mouse +Sel mode does not support using a `double' value to follow links +using double-clicks." + (and initial final mouse-1-click-follows-link + (eq (car initial) 'down-mouse-1) + (mouse-on-link-p (event-start initial)) + (= (posn-point (event-start initial)) + (posn-point (event-end final))) + (= (event-click-count initial) 1) + (or (not (integerp mouse-1-click-follows-link)) + (let ((t0 (posn-timestamp (event-start initial))) + (t1 (posn-timestamp (event-end final)))) + (and (integerp t0) (integerp t1) + (if (> mouse-1-click-follows-link 0) + (<= (- t1 t0) mouse-1-click-follows-link) + (< (- t0 t1) mouse-1-click-follows-link))))))) + ;;=== Paste =============================================================== (defun mouse-insert-selection (event arg) @@ -701,7 +743,8 @@ If `mouse-yank-at-point' is non-nil, insert at point instead." (mouse-set-point event)) (when mouse-sel-get-selection-function (push-mark (point) 'nomsg) - (insert (or (funcall mouse-sel-get-selection-function selection) "")))) + (insert-for-yank + (or (funcall mouse-sel-get-selection-function selection) "")))) ;;=== Handle loss of selections =========================================== @@ -712,5 +755,5 @@ If `mouse-yank-at-point' is non-nil, insert at point instead." (provide 'mouse-sel) -;;; arch-tag: 86e6c73f-deaa-48d3-a24e-c565fda1f7d7 +;; arch-tag: 86e6c73f-deaa-48d3-a24e-c565fda1f7d7 ;;; mouse-sel.el ends here