diff options
Diffstat (limited to 'lisp/mouse.el')
-rw-r--r-- | lisp/mouse.el | 114 |
1 files changed, 71 insertions, 43 deletions
diff --git a/lisp/mouse.el b/lisp/mouse.el index 27f2acbc76..2a9a62feae 100644 --- a/lisp/mouse.el +++ b/lisp/mouse.el @@ -34,6 +34,11 @@ ;; Indent track-mouse like progn. (put 'track-mouse 'lisp-indent-function 0) +(defgroup mouse nil + "Input from the mouse." ;; "Mouse support." + :group 'environment + :group 'editing) + (defcustom mouse-yank-at-point nil "If non-nil, mouse yank commands yank at point instead of at click." :type 'boolean @@ -97,35 +102,44 @@ Expects to be bound to `down-mouse-1' in `key-translation-map'." (when (and mouse-1-click-follows-link (eq (if (eq mouse-1-click-follows-link 'double) 'double-down-mouse-1 'down-mouse-1) - (car-safe last-input-event)) - (mouse-on-link-p (event-start last-input-event)) - (or mouse-1-click-in-non-selected-windows - (eq (selected-window) - (posn-window (event-start last-input-event))))) - (let ((timedout - (sit-for (if (numberp mouse-1-click-follows-link) - (/ (abs mouse-1-click-follows-link) 1000.0) - 0)))) - (if (if (and (numberp mouse-1-click-follows-link) - (>= mouse-1-click-follows-link 0)) - timedout (not timedout)) - nil - - (let ((event (read-key))) ;Use read-key so it works for xterm-mouse-mode! - (if (eq (car-safe event) (if (eq mouse-1-click-follows-link 'double) - 'double-mouse-1 'mouse-1)) - ;; Turn the mouse-1 into a mouse-2 to follow links. - (let ((newup (if (eq mouse-1-click-follows-link 'double) - 'double-mouse-2 'mouse-2))) - ;; If mouse-2 has never been done by the user, it doesn't have - ;; the necessary property to be interpreted correctly. - (unless (get newup 'event-kind) - (put newup 'event-kind (get (car event) 'event-kind))) - (push (cons newup (cdr event)) unread-command-events) - ;; Don't change the down event, only the up-event (bug#18212). - nil) - (push event unread-command-events) - nil)))))) + (car-safe last-input-event))) + (let ((action (mouse-on-link-p (event-start last-input-event)))) + (when (and action + (or mouse-1-click-in-non-selected-windows + (eq (selected-window) + (posn-window (event-start last-input-event))))) + (let ((timedout + (sit-for (if (numberp mouse-1-click-follows-link) + (/ (abs mouse-1-click-follows-link) 1000.0) + 0)))) + (if (if (and (numberp mouse-1-click-follows-link) + (>= mouse-1-click-follows-link 0)) + timedout (not timedout)) + nil + ;; Use read-key so it works for xterm-mouse-mode! + (let ((event (read-key))) + (if (eq (car-safe event) + (if (eq mouse-1-click-follows-link 'double) + 'double-mouse-1 'mouse-1)) + (progn + ;; Turn the mouse-1 into a mouse-2 to follow links, + ;; but only if ‘mouse-on-link-p’ hasn’t returned a + ;; string or vector (see its docstring). + (if (or (stringp action) (vectorp action)) + (push (aref action 0) unread-command-events) + (let ((newup (if (eq mouse-1-click-follows-link 'double) + 'double-mouse-2 'mouse-2))) + ;; If mouse-2 has never been done by the user, it + ;; doesn't have the necessary property to be + ;; interpreted correctly. + (unless (get newup 'event-kind) + (put newup 'event-kind (get (car event) 'event-kind))) + (push (cons newup (cdr event)) unread-command-events))) + ;; Don't change the down event, only the up-event + ;; (bug#18212). + nil) + (push event unread-command-events) + nil)))))))) (define-key key-translation-map [down-mouse-1] #'mouse--down-1-maybe-follows-link) @@ -155,7 +169,7 @@ items `Turn Off' and `Help'." (if (fboundp mm-fun) ; bug#20201 `(keymap ,indicator - (turn-off menu-item "Turn Off minor mode" ,mm-fun) + (turn-off menu-item "Turn off minor mode" ,mm-fun) (help menu-item "Help for minor mode" (lambda () (interactive) (describe-function ',mm-fun))))))) @@ -411,10 +425,8 @@ must be one of the symbols `header', `mode', or `vertical'." (let ((divider-width (frame-right-divider-width frame))) (when (and (or (not (numberp divider-width)) (zerop divider-width)) - (eq (cdr (assq 'vertical-scroll-bars - (frame-parameters frame))) - 'left)) - (setq window (window-in-direction 'left window t)))))) + (eq (frame-parameter frame 'vertical-scroll-bars) 'left)) + (setq window (window-in-direction 'left window t)))))) (let* ((exitfun nil) (move @@ -531,15 +543,29 @@ must be one of the symbols `header', `mode', or `vertical'." (interactive "e") (mouse-drag-line start-event 'vertical)) +(defcustom mouse-select-region-move-to-beginning nil + "Effect of selecting a region extending backward from double click. +Nil means keep point at the position clicked (region end); +non-nil means move point to beginning of region." + :type '(choice (const :tag "Don't move point" nil) + (const :tag "Move point to beginning of region" t)) + :group 'mouse + :version "25.2") + (defun mouse-set-point (event &optional promote-to-region) "Move point to the position clicked on with the mouse. This should be bound to a mouse click event type. -If PROMOTE-TO-REGION is non-nil and event is a multiple-click, -select the corresponding element around point." +If PROMOTE-TO-REGION is non-nil and event is a multiple-click, select +the corresponding element around point, with the resulting position of +point determined by `mouse-select-region-move-to-beginning'." (interactive "e\np") (mouse-minibuffer-check event) (if (and promote-to-region (> (event-click-count event) 1)) - (mouse-set-region event) + (progn + (mouse-set-region event) + (when mouse-select-region-move-to-beginning + (when (> (posn-point (event-start event)) (region-beginning)) + (exchange-point-and-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)))) @@ -807,14 +833,16 @@ The region will be defined with mark and point." (setq mouse-selection-click-count-buffer (current-buffer)) (deactivate-mark) (let* ((scroll-margin 0) ; Avoid margin scrolling (Bug#9541). + (start-posn (event-start start-event)) + (start-point (posn-point start-posn)) + (start-window (posn-window start-posn)) + (_ (with-current-buffer (window-buffer start-window) + (setq deactivate-mark nil))) ;; 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) - (start-posn (event-start start-event)) - (start-point (posn-point start-posn)) - (start-window (posn-window start-posn)) (bounds (window-edges start-window)) (make-cursor-line-fully-visible nil) (top (nth 1 bounds)) @@ -1619,8 +1647,8 @@ and selects that window." (let ((others-list (mouse-buffer-menu-alist ;; we don't need split-by-major-mode any more, - ;; so we can ditch it with nconc. - (apply 'nconc (mapcar 'cddr split-by-major-mode))))) + ;; so we can ditch it with nconc (mapcan). + (mapcan 'cddr split-by-major-mode)))) (and others-list (setq subdivided-menus (cons (cons "Others" others-list) @@ -1697,7 +1725,7 @@ and selects that window." ;; Font selection. (defun font-menu-add-default () - (let* ((default (cdr (assq 'font (frame-parameters (selected-frame))))) + (let* ((default (frame-parameter nil 'font)) (font-alist x-fixed-font-alist) (elt (or (assoc "Misc" font-alist) (nth 1 font-alist)))) (if (assoc "Default" elt) |