# HG changeset patch # User Stefan Monnier # Date 1026826025 0 # Node ID 3b394c7ff111440eb1d00214e3a403c31f03e314 # Parent c68f80aab1e28adaf8cdafb7c719e7a480d5d0f0 (mouse-sel-mode): Use define-minor-mode. Fold mouse-sel-bindings into it. (mouse-sel-bound-events): Turn it into an alist. (mouse-insert-selection): Delegate to mouse-yank-at-click if mouse-sel-default-bindings asks for it. diff -r c68f80aab1e2 -r 3b394c7ff111 lisp/mouse-sel.el --- a/lisp/mouse-sel.el Tue Jul 16 12:25:41 2002 +0000 +++ b/lisp/mouse-sel.el Tue Jul 16 13:27:05 2002 +0000 @@ -93,8 +93,9 @@ ;; ;; Mouse sets selection, and pastes from kill-ring ;; mouse-1 mouse-select -;; mouse-2 mouse-yank-at-click +;; mouse-2 mouse-insert-selection ;; mouse-3 mouse-extend +;; In this mode, mouse-insert-selection just calls mouse-yank-at-click. ;; ;; Selection/kill-ring interaction is retained ;; interprogram-cut-function = x-select-text @@ -149,18 +150,6 @@ "Mouse selection enhancement." :group 'mouse) -(defcustom mouse-sel-mode nil - "Toggle Mouse Sel mode. -When Mouse Sel mode is enabled, mouse selection is enhanced in various ways. -Setting this variable directly does not take effect; -use either \\[customize] or the function `mouse-sel-mode'." - :set (lambda (symbol value) - (mouse-sel-mode (or value 0))) - :initialize 'custom-initialize-default - :type 'boolean - :group 'mouse-sel - :require 'mouse-sel) - (defcustom mouse-sel-leave-point-near-mouse t "*Leave point near last mouse position. If non-nil, \\[mouse-select] and \\[mouse-extend] will leave point at the end @@ -181,10 +170,38 @@ (other :tag "default bindings" t)) :group 'mouse-sel) +;;=== Key bindings ======================================================== + +(defconst mouse-sel-bound-events + '(;; Primary selection bindings. + ;; + ;; Bind keys to `ignore' instead of unsetting them because modes may + ;; bind `down-mouse-1', for instance, without binding `mouse-1'. + ;; If we unset `mouse-1', this leads to a bitch_at_user when the + ;; mouse goes up because no matching binding is found for that. + ([mouse-1] . ignore) + ([drag-mouse-1] . ignore) + ([mouse-3] . ignore) + ([down-mouse-1] . mouse-select) + ([down-mouse-3] . mouse-extend) + ([mouse-2] . mouse-insert-selection) + ;; Secondary selection bindings. + ([M-mouse-1] . ignore) + ([M-drag-mouse-1] . ignore) + ([M-mouse-3] . ignore) + ([M-down-mouse-1] . mouse-select-secondary) + ([M-mouse-2] . mouse-insert-secondary) + ([M-down-mouse-3] . mouse-extend-secondary)) + "An alist of events that `mouse-sel-mode' binds.") + ;;=== User Command ======================================================== +(defvar mouse-sel-original-bindings nil) +(defvar mouse-sel-original-interprogram-cut-function nil) +(defvar mouse-sel-original-interprogram-cut-function nil) + ;;;###autoload -(defun mouse-sel-mode (&optional arg) +(define-minor-mode mouse-sel-mode "Toggle Mouse Sel mode. With prefix ARG, turn Mouse Sel mode on if and only if ARG is positive. Returns the new status of Mouse Sel mode (non-nil means on). @@ -203,10 +220,10 @@ Quad-clicking selects paragraphs. - Selecting sets the region & X primary selection, but does NOT affect -the kill-ring, nor do the kill-ring function change the X selection. +the `kill-ring', nor do the kill-ring functions change the X selection. Because the mouse handlers set the primary selection directly, -mouse-sel sets the variables interprogram-cut-function and -interprogram-paste-function to nil. +mouse-sel sets the variables `interprogram-cut-function' and +`interprogram-paste-function' to nil. - Clicking mouse-2 inserts the contents of the primary selection at the mouse position (or point, if `mouse-yank-at-point' is non-nil). @@ -219,93 +236,35 @@ - M-mouse-1, M-mouse-2 & M-mouse-3 work similarly to mouse-1, mouse-2 & mouse-3, but operate on the X secondary selection rather than the primary selection and region." - (interactive "P") - (let ((on-p (if arg - (> (prefix-numeric-value arg) 0) - (not mouse-sel-mode)))) - (if on-p + :global t + (if mouse-sel-mode + (progn (add-hook 'x-lost-selection-hooks 'mouse-sel-lost-selection-hook) - (remove-hook 'x-lost-selection-hooks 'mouse-sel-lost-selection-hook)) - (mouse-sel-bindings on-p) - (setq mouse-sel-mode on-p))) - -;;=== Key bindings ======================================================== - -(defconst mouse-sel-bound-events - '([down-mouse-1] [mouse-1] [drag-mouse-1] - [mouse-2] - [down-mouse-3] [mouse-3] - [M-mouse-2] - [M-down-mouse-1] [M-mouse-1] [M-drag-mouse-1] - [M-down-mouse-3] [M-mouse-3]) - "A list of events that mouse-sel binds.") - -(defun mouse-sel-bindings (bind) - (cond - - ;; Default mouse-sel bindings - ((and bind mouse-sel-default-bindings) + (when mouse-sel-default-bindings + ;; Save original bindings and replace them with new ones. + (setq mouse-sel-original-bindings + (mapcar (lambda (binding) + (let ((event (car binding))) + (prog1 (cons event (lookup-key global-map event)) + (global-set-key event (cdr binding))))) + mouse-sel-bound-events)) + ;; Update interprogram functions. + (setq mouse-sel-original-interprogram-cut-function + interprogram-cut-function + mouse-sel-original-interprogram-paste-function + interprogram-paste-function) + (unless (eq mouse-sel-default-bindings 'interprogram-cut-paste) + (setq interprogram-cut-function nil + interprogram-paste-function nil)))) - ;; Save original bindings - (setq mouse-sel-original-bindings nil) - (mapc (function - (lambda (event) - (setq mouse-sel-original-bindings - (cons (cons event (lookup-key global-map event)) - mouse-sel-original-bindings)))) - mouse-sel-bound-events) - (setq mouse-sel-original-interprogram-cut-function - interprogram-cut-function - mouse-sel-original-interprogram-paste-function - interprogram-paste-function) - - ;; Primary selection bindings. - ;; - ;; Bind keys to `ignore' instead of unsetting them because - ;; modes may bind `down-mouse-1', for instance, without - ;; binding other `up-mouse-1' or `mouse-1'. If we unset - ;; `mouse-1', this leads to a bitch_at_user when the mouse - ;; goes up because no matching binding is found for that. - (global-set-key [mouse-1] 'ignore) - (global-set-key [drag-mouse-1] 'ignore) - (global-set-key [mouse-3] 'ignore) - (global-set-key [down-mouse-1] 'mouse-select) - (unless (eq mouse-sel-default-bindings 'interprogram-cut-paste) - (global-set-key [mouse-2] 'mouse-insert-selection) - (setq interprogram-cut-function nil - interprogram-paste-function nil)) - (global-set-key [down-mouse-3] 'mouse-extend) - - ;; Secondary selection bindings. - (global-set-key [M-mouse-1] 'ignore) - (global-set-key [M-drag-mouse-1] 'ignore) - (global-set-key [M-mouse-3] 'ignore) - (global-set-key [M-down-mouse-1] 'mouse-select-secondary) - (global-set-key [M-mouse-2] 'mouse-insert-secondary) - (global-set-key [M-down-mouse-3] 'mouse-extend-secondary)) - - ((not bind) ;; Restore original bindings - (mapc (function - (lambda (binding) - (if (cdr binding) - (global-set-key (car binding) (cdr binding)) - (global-unset-key (car binding))))) - mouse-sel-original-bindings) - (setq interprogram-cut-function + (remove-hook 'x-lost-selection-hooks 'mouse-sel-lost-selection-hook) + (dolist (binding mouse-sel-original-bindings) + (global-set-key (car binding) (cdr binding))) + (setq interprogram-cut-function mouse-sel-original-interprogram-cut-function interprogram-paste-function - mouse-sel-original-interprogram-paste-function)) - - )) - -;;=== Command Variable ==================================================== - -;; This has to come after the function `mouse-sel-mode' and its callee. -;; An alternative is to put the option `mouse-sel-mode' here and remove its -;; `:initialize' keyword. -(when mouse-sel-mode - (mouse-sel-mode t)) + mouse-sel-original-interprogram-paste-function))) ;;=== Internal Variables/Constants ======================================== @@ -711,11 +670,13 @@ ;;=== Paste =============================================================== -(defun mouse-insert-selection (event) +(defun mouse-insert-selection (event arg) "Insert the contents of the PRIMARY selection at mouse click. If `mouse-yank-at-point' is non-nil, insert at point instead." - (interactive "e") - (mouse-insert-selection-internal 'PRIMARY event)) + (interactive "e\nP") + (if (eq mouse-sel-default-bindings 'interprogram-cut-paste) + (mouse-yank-at-click event arg) + (mouse-insert-selection-internal 'PRIMARY event))) (defun mouse-insert-secondary (event) "Insert the contents of the SECONDARY selection at mouse click.