comparison lisp/mouse.el @ 4738:76a2ea569de5

(mouse-set-region): Put region in kill ring. (mouse-drag-region): Handle double and triple clicks when displaying region and when setting it. (mouse-skip-word, mouse-start-end): New functions.
author Richard M. Stallman <rms@gnu.org>
date Fri, 17 Sep 1993 21:26:18 +0000
parents 168bcc1aeea3
children c63ce262aa4d
comparison
equal deleted inserted replaced
4737:430cee1995ab 4738:76a2ea569de5
104 (select-window (posn-window posn)) 104 (select-window (posn-window posn))
105 (if (numberp (posn-point posn)) 105 (if (numberp (posn-point posn))
106 (goto-char (posn-point posn))))) 106 (goto-char (posn-point posn)))))
107 107
108 (defun mouse-set-region (click) 108 (defun mouse-set-region (click)
109 "Set the region to the text that the mouse is dragged over. 109 "Set the region to the text dragged over, and copy to kill ring.
110 This should be bound to a mouse drag event." 110 This should be bound to a mouse drag event."
111 (interactive "e") 111 (interactive "e")
112 (let ((posn (event-start click)) 112 (let ((posn (event-start click))
113 (end (event-end click))) 113 (end (event-end click)))
114 (select-window (posn-window posn)) 114 (select-window (posn-window posn))
119 (eq (framep (selected-frame)) 'x)) 119 (eq (framep (selected-frame)) 'x))
120 (sit-for 1)) 120 (sit-for 1))
121 (push-mark) 121 (push-mark)
122 (set-mark (point)) 122 (set-mark (point))
123 (if (numberp (posn-point end)) 123 (if (numberp (posn-point end))
124 (goto-char (posn-point end))))) 124 (goto-char (posn-point end)))
125 ;; Don't set this-command to kill-region, so that a following
126 ;; C-w will not double the text in the kill ring.
127 (let (this-command)
128 (copy-region-as-kill (mark) (point)))))
125 129
126 (defvar mouse-scroll-delay 0.25 130 (defvar mouse-scroll-delay 0.25
127 "*The pause between scroll steps caused by mouse drags, in seconds. 131 "*The pause between scroll steps caused by mouse drags, in seconds.
128 If you drag the mouse beyond the edge of a window, Emacs scrolls the 132 If you drag the mouse beyond the edge of a window, Emacs scrolls the
129 window to bring the text beyond that edge into view, with a delay of 133 window to bring the text beyond that edge into view, with a delay of
172 (bounds (window-edges start-window)) 176 (bounds (window-edges start-window))
173 (top (nth 1 bounds)) 177 (top (nth 1 bounds))
174 (bottom (if (window-minibuffer-p start-window) 178 (bottom (if (window-minibuffer-p start-window)
175 (nth 3 bounds) 179 (nth 3 bounds)
176 ;; Don't count the mode line. 180 ;; Don't count the mode line.
177 (1- (nth 3 bounds))))) 181 (1- (nth 3 bounds))))
182 (click-count (1- (event-click-count start-event))))
178 (mouse-set-point start-event) 183 (mouse-set-point start-event)
179 (move-overlay mouse-drag-overlay 184 (let ((range (mouse-start-end start-point start-point click-count)))
180 start-point start-point 185 (move-overlay mouse-drag-overlay (car range) (nth 1 range)
181 (window-buffer start-window)) 186 (window-buffer start-window)))
182 (deactivate-mark) 187 (deactivate-mark)
183 (let (event end end-point) 188 (let (event end end-point)
184 (track-mouse 189 (track-mouse
185 (while (progn 190 (while (progn
186 (setq event (read-event)) 191 (setq event (read-event))
199 204
200 ;; Are we moving within the original window? 205 ;; Are we moving within the original window?
201 ((and (eq (posn-window end) start-window) 206 ((and (eq (posn-window end) start-window)
202 (integer-or-marker-p end-point)) 207 (integer-or-marker-p end-point))
203 (goto-char end-point) 208 (goto-char end-point)
204 (move-overlay mouse-drag-overlay 209 (let ((range (mouse-start-end start-point (point) click-count)))
205 start-point (point))) 210 (move-overlay mouse-drag-overlay (car range) (nth 1 range))))
206 211
207 ;; Are we moving on a different window on the same frame? 212 ;; Are we moving on a different window on the same frame?
208 ((and (windowp (posn-window end)) 213 ((and (windowp (posn-window end))
209 (eq (window-frame (posn-window end)) start-frame)) 214 (eq (window-frame (posn-window end)) start-frame))
210 (let ((mouse-row 215 (let ((mouse-row
231 mouse-drag-overlay start-point)))))))) 236 mouse-drag-overlay start-point))))))))
232 237
233 (if (and (eq (get (event-basic-type event) 'event-kind) 'mouse-click) 238 (if (and (eq (get (event-basic-type event) 'event-kind) 'mouse-click)
234 (eq (posn-window (event-end event)) start-window) 239 (eq (posn-window (event-end event)) start-window)
235 (numberp (posn-point (event-end event)))) 240 (numberp (posn-point (event-end event))))
236 (progn 241 (let ((fun (key-binding (vector (car event)))))
237 (mouse-set-point event) 242 (if (memq fun '(mouse-set-region mouse-set-point))
238 (if (= (point) start-point) 243 (progn
239 (deactivate-mark) 244 (push-mark (overlay-start mouse-drag-overlay) t t)
240 (set-mark start-point)))) 245 (goto-char (overlay-end mouse-drag-overlay)))
246 (if (fboundp fun)
247 (funcall fun event)))))
241 (delete-overlay mouse-drag-overlay)))) 248 (delete-overlay mouse-drag-overlay))))
242 249
243 ;;;! (defun mouse-drag-region (click) 250 ;; Commands to handle xterm-style multiple clicks.
244 ;;;! "Set the region to the text that the mouse is dragged over. 251
245 ;;;! This must be bound to a button-down mouse event." 252 (defun mouse-skip-word (dir)
246 ;;;! (interactive "e") 253 "Skip over word, over whitespace, or over identical punctuation.
247 ;;;! (let ((posn (event-start click)) 254 If DIR is positive skip forward; if negative, skip backward."
248 ;;;! done event (mark-active nil)) 255 (let* ((char (following-char))
249 ;;;! (select-window (posn-window posn)) 256 (syntax (char-to-string (char-syntax char))))
250 ;;;! ;; Set point temporarily, so user sees where it is. 257 (if (or (string= syntax "w") (string= syntax " "))
251 ;;;! (if (numberp (posn-point posn)) 258 (if (< dir 0)
252 ;;;! (goto-char (posn-point posn))) 259 (skip-syntax-backward syntax)
253 ;;;! ;; Turn off the old mark when we set up an empty region. 260 (skip-syntax-forward syntax))
254 ;;;! (setq deactivate-mark t))) 261 (if (< dir 0)
255 ;;;! 262 (while (= (preceding-char) char)
256 ;;;! ;;;Nice hack, but too slow, so not normally in use. 263 (forward-char -1))
257 ;;;! (defun mouse-drag-region-1 (click) 264 (while (= (following-char) char)
258 ;;;! "Set the region to the text that the mouse is dragged over. 265 (forward-char 1))))))
259 ;;;! This must be bound to a button-down mouse event." 266
260 ;;;! (interactive "e") 267 ;; Return a list of region bounds based on START and END according to MODE.
261 ;;;! (let (newmark) 268 ;; If MODE is 0 then set point to (min START END), mark to (max START END).
262 ;;;! (let ((posn (event-start click)) 269 ;; If MODE is 1 then set point to start of word at (min START END),
263 ;;;! done event omark (mark-active t)) 270 ;; mark to end of word at (max START END).
264 ;;;! (select-window (posn-window posn)) 271 ;; If MODE is 2 then do the same for lines.
265 ;;;! (setq omark (and mark-active (mark))) 272 ;; Optional KEEP-END if non-nil means do not change end.
266 ;;;! (if (numberp (posn-point posn)) 273 (defun mouse-start-end (start end mode &optional keep-end)
267 ;;;! (goto-char (posn-point posn))) 274 (if (> start end)
268 ;;;! ;; Set mark temporarily, so highlighting does what we want. 275 (let ((temp start))
269 ;;;! (set-marker (mark-marker) (point)) 276 (setq start end
270 ;;;! (track-mouse 277 end temp)))
271 ;;;! (while (not done) 278 (cond ((= mode 0)
272 ;;;! (setq event (read-event)) 279 (list start end))
273 ;;;! (if (eq (car-safe event) 'mouse-movement) 280 ((and (= mode 1)
274 ;;;! (goto-char (posn-point (event-start event))) 281 (= start end)
275 ;;;! ;; Exit when we get the drag event; ignore that event. 282 (= (char-syntax (char-after start)) ?\())
276 ;;;! (setq done t)))) 283 (list start (save-excursion (forward-sexp 1) (point))))
277 ;;;! (if (/= (mark) (point)) 284 ((and (= mode 1)
278 ;;;! (setq newmark (mark))) 285 (= start end)
279 ;;;! ;; Restore previous mark status. 286 (= (char-syntax (char-after start)) ?\)))
280 ;;;! (if omark (set-marker (mark-marker) omark))) 287 (list (save-excursion
281 ;;;! ;; Now, if we dragged, set the mark at the proper place. 288 (goto-char (1+ start))
282 ;;;! (if newmark 289 (backward-sexp 1))
283 ;;;! (push-mark newmark t t) 290 (1+ start)))
284 ;;;! ;; Turn off the old mark when we set up an empty region. 291 ((= mode 1)
285 ;;;! (setq deactivate-mark t)))) 292 (list (save-excursion
293 (goto-char start)
294 (mouse-skip-word -1)
295 (point))
296 (save-excursion
297 (goto-char end)
298 (mouse-skip-word 1)
299 (point))))
300 ((= mode 2)
301 (list (save-excursion
302 (goto-char start)
303 (beginning-of-line 1)
304 (point))
305 (save-excursion
306 (goto-char end)
307 (forward-line 1)
308 (point))))))
286 309
287 ;; Subroutine: set the mark where CLICK happened, 310 ;; Subroutine: set the mark where CLICK happened,
288 ;; but don't do anything else. 311 ;; but don't do anything else.
289 (defun mouse-set-mark-fast (click) 312 (defun mouse-set-mark-fast (click)
290 (let ((posn (event-start click))) 313 (let ((posn (event-start click)))
981 1004
982 (define-key global-map [down-mouse-1] 'mouse-drag-region) 1005 (define-key global-map [down-mouse-1] 'mouse-drag-region)
983 (global-set-key [mouse-1] 'mouse-set-point) 1006 (global-set-key [mouse-1] 'mouse-set-point)
984 (global-set-key [drag-mouse-1] 'mouse-set-region) 1007 (global-set-key [drag-mouse-1] 'mouse-set-region)
985 1008
1009 ;; These are tested for in mouse-drag-region.
1010 (global-set-key [double-mouse-1] 'mouse-set-point)
1011 (global-set-key [triple-mouse-1] 'mouse-set-point)
1012
986 (global-set-key [mouse-2] 'mouse-yank-at-click) 1013 (global-set-key [mouse-2] 'mouse-yank-at-click)
987 (global-set-key [mouse-3] 'mouse-save-then-kill) 1014 (global-set-key [mouse-3] 'mouse-save-then-kill)
988 1015
989 ;; By binding these to down-going events, we let the user use the up-going 1016 ;; By binding these to down-going events, we let the user use the up-going
990 ;; event to make the selection, saving a click. 1017 ;; event to make the selection, saving a click.