comparison shared/motion4.el @ 0:107d592c5f4a

DICE versions, used by pers/common, recursive, I think/hope
author Henry S. Thompson <ht@inf.ed.ac.uk>
date Mon, 08 Feb 2021 11:44:37 +0000
parents
children
comparison
equal deleted inserted replaced
-1:000000000000 0:107d592c5f4a
1 ;;; Copyright (C) 1991 Christopher J. Love
2 ;;;
3 ;;; This file is for use with Epoch, a modified version of GNU Emacs.
4 ;;; Requires Epoch 4.0 or later.
5 ;;;
6 ;;; This code is distributed in the hope that it will be useful,
7 ;;; bute WITHOUT ANY WARRANTY. No author or distributor accepts
8 ;;; responsibility to anyone for the consequences of using this code
9 ;;; or for whether it serves any particular purpose or works at all,
10 ;;; unless explicitly stated in a written agreement.
11 ;;;
12 ;;; Everyone is granted permission to copy, modify and redistribute
13 ;;; this code, but only under the conditions described in the
14 ;;; GNU Emacs General Public License, except the original author nor his
15 ;;; agents are bound by the License in their use of this code.
16 ;;; (These special rights for the author in no way restrict the rights of
17 ;;; others given in the License or this prologue)
18 ;;; A copy of this license is supposed to have been given to you along
19 ;;; with Epoch so you can know your rights and responsibilities.
20 ;;; It should be in a file named COPYING. Among other things, the
21 ;;; copyright notice and this notice must be preserved on all copies.
22 ;;;
23 ;;; $Revision: 1.2 $
24 ;;; $Source: /home/user5/ht/emacs/shared/RCS/motion4.el,v $
25 ;;; $Date: 1992/03/18 21:44:10 $
26 ;;; $Author: ht $
27 ;;;
28 ;;; motion.el - provide draggin/hi-lighting of primary selection
29 ;;;
30 ;;; Original version by Alan Carroll
31 ;;; Epoch 4.0 modifications by Chris Love
32 ;;; Abort-isearch and other ideas from Ken Laprade and others.
33 ;;;
34 (provide 'motion)
35 (redisplay-screen) ; fix epoch4.0a race bug?
36 (require 'zone)
37 (require 'mouse)
38
39 ;;; ------------------------------------------------------------------------
40 ;;; Interface values
41 (defvar horizontal-drag-inc 5
42 "Number of columns to scroll when the pointer is to the left or right of the window")
43 (defvar vertical-drag-inc 2
44 "Number of lines to scroll when the pointer is above or below the edge of the window")
45
46 (defvar mouse::downp nil "State variable for mouse dragging internals")
47 (defvar mouse::last-point -1 "Last location of a motion event")
48
49 (setq epoch::zones-modify-buffer nil)
50 (defvar motion::style nil "style used by drag zones")
51
52 (defvar drag-zone nil
53 "Epoch zone to be used for hilighting selected text region."
54 )
55 (setq-default drag-zone nil)
56 (setq-default mouse-down-marker nil)
57
58 ;;; ------------------------------------------------------------------------
59 ;;; Set window-setup-hook to call motion::init(), which sets default
60 ;;; style for zone dragging. Default style is underlining; can be changed
61 ;;; in .emacs file.
62 (epoch-add-setup-hook 'motion::init)
63
64 (defun motion::init ()
65 (and (not motion::style) (setq motion::style (make-style)))
66 (set-style-foreground motion::style (foreground))
67 (set-style-background motion::style (background))
68 (set-style-underline motion::style (foreground))
69 ;; enable the handler
70 (push-event 'motion 'motion::handler)
71 ;; set up hints on all the current screens
72 (dolist (s (screen-list t)) (epoch::set-motion-hints t s))
73 ;; enable hints on future screens
74 (push '(motion-hints t) epoch::screen-properties)
75 )
76
77 ;;; ------------------------------------------------------------------------
78 (defun set-mouse-marker (&optional location)
79 (if (null mouse-down-marker)
80 (setq mouse-down-marker (make-marker))
81 )
82 (set-marker mouse-down-marker (or location (point)))
83 )
84
85 ;;; --------------------------------------------------------------------------
86 ;;; Functions to provide dragging & hilighting.
87 ;;; arg is a list of ( POINT BUFFER WINDOW SCREEN )
88 (defun end-mouse-drag (arg)
89 (setq mouse::last-point -1) ;always do this cleanup
90 (when mouse::downp
91 (setq mouse::downp nil)
92 (mouse::copy-zone drag-zone)
93 (let (
94 (s (and drag-zone (zone-start drag-zone)))
95 (e (and drag-zone (zone-end drag-zone)))
96 )
97 (if (null s) (setq s 1))
98 (if (null e) (setq e 1))
99 (if (zonep drag-zone)
100 (if (<= (point) s)
101 (progn
102 (push-mark e t)
103 (goto-char s)
104 )
105 ;; ELSE point is past drag zone start
106 (progn
107 (push-mark s t)
108 (goto-char e)
109 )
110 )
111 )
112 )
113 )
114 )
115
116 (defun start-mouse-drag (arg)
117 (when arg
118 (setq mouse::downp 'start)
119 ; (message "%s" arg)
120 (mouse::set-point arg)
121 (abort-isearch)
122 (set-mouse-marker)
123 (setq mouse::last-point (point))
124 (if drag-zone
125 (progn
126 (message "ddz")
127 (delete-zone drag-zone)
128 (setq drag-zone nil)
129 (redisplay-screen)
130 )
131 )
132 )
133 )
134
135 (defun extend-mouse-drag (arg)
136 (setq mouse::downp 'extend)
137 (let
138 (
139 (m1 (and drag-zone (zone-start drag-zone)))
140 (m2 (and drag-zone (zone-end drag-zone)))
141 (spot (car arg)) ;point of the mouse click.
142 )
143 (if (null m1) (setq m1 0))
144 (if (null m2) (setq m2 0))
145 (cond
146 ((or (null drag-zone) (null mouse-down-marker))
147 (setq drag-zone (add-zone (point) spot motion::style) )
148 (set-zone-transient drag-zone t)
149 (set-mouse-marker)
150 )
151 ((<= spot m1)
152 (setq drag-zone (move-zone drag-zone spot m2) )
153 (set-mouse-marker m2)
154 )
155 ((>= spot m2)
156 (setq drag-zone (move-zone drag-zone m1 spot) )
157 (set-mouse-marker m1)
158 )
159 ((<= mouse-down-marker spot)
160 (setq drag-zone (move-zone drag-zone m1 spot) )
161 (set-mouse-marker m1)
162 )
163 (t
164 (setq drag-zone (move-zone drag-zone spot m2) )
165 (set-mouse-marker m2)
166 )
167 )
168 (epoch::redisplay-screen)
169 (setq mouse::last-point (point))
170 )
171 )
172
173 ;;; ------------------------------------------------------------------------
174 ;;; Define the handler for dragging, etc.
175 (defun motion::handler (type value scr)
176 (if (null mouse-down-marker) (set-mouse-marker))
177 (if (and (boundp 'mouse::downp) mouse::downp)
178 (mouse-sweep-update)
179 )
180 )
181
182 ;;;
183 (defun mouse-sweep-update()
184 (let*
185 (
186 drag-m1
187 drag-m2
188 pnt
189 pos
190 x
191 y
192 (w (selected-window))
193 (out-of-bounds t)
194 (epoch::event-handler-abort nil)
195 (w-edges (window-pixedges w))
196 (left (car w-edges))
197 (top (elt w-edges 1))
198 (right (- (elt w-edges 2) left 1))
199 (bottom (- (elt w-edges 4) top 1))
200 )
201 (while
202 (and
203 out-of-bounds
204 (setq pos (query-pointer))
205 (/= 0 (logand mouse-any-mask (elt pos 2)))
206 )
207 ;;convert to window relative co-ordinates
208 (setq x (- (car pos) left))
209 (setq y (- (elt pos 1) top))
210 (setq out-of-bounds
211 (not (and (<= 0 y) (<= y bottom) (<= 0 x) (<= x right)))
212 )
213 ;; scrolling conditions
214 (condition-case errno
215 (progn
216 (if (< y 0) (scroll-down vertical-drag-inc))
217 (if (> y bottom) (scroll-up vertical-drag-inc))
218 )
219 (error ) ;nothing, just catch it
220 )
221 ;; Disable horizontal scrolling.
222 ; (if (< x left) (scroll-right horizontal-drag-inc))
223 ; (if (> x right) (scroll-left horizontal-drag-inc))
224 (setq y (max 1 (min bottom y)))
225 (setq x (max 0 (min right x)))
226 (setq pnt (car (epoch::coords-to-point (+ x left) (+ y top))))
227 (when (/= mouse::last-point pnt)
228 (if (> mouse-down-marker pnt)
229 (progn
230 (setq drag-m1 pnt)
231 (setq drag-m2 (marker-position mouse-down-marker))
232 )
233 (progn
234 (setq drag-m1 (marker-position mouse-down-marker))
235 (setq drag-m2 (1+ pnt))
236 )
237 )
238 ;; moved this in here so that zone won't get made if
239 ;; only motion is jitter within a single character
240 ;; this fixes a bunch of bogus (often empty)
241 ;; entries in the kill ring
242 (if drag-zone
243 (move-zone drag-zone drag-m1 drag-m2)
244 (progn (setq drag-zone
245 (add-zone drag-m1 drag-m2 motion::style )
246 )
247 (set-zone-transient drag-zone t)
248 )
249 )
250 (redisplay-screen)
251 )
252 (setq mouse::last-point pnt)
253 )
254 )
255 )
256
257 ;;; ------------------------------------------------------------------------
258 ;;; Code for selecting lines using motion events. Assumes that the line is
259 ;;; left unmarked on zone up
260 (defvar mouse::line-zone nil "Zone for selected line")
261 ;;;
262 (defun mouse-select-line-start (arg)
263 (mouse::set-point arg) ;go there
264 (setq mouse::last-point (point))
265 (let ( bol )
266 (save-excursion
267 (beginning-of-line)
268 (setq bol (point))
269 (end-of-line)
270 (setq mouse::line-zone (add-zone bol (point) motion::style))
271 )
272 )
273 (push-event 'motion 'mouse-select-line-update)
274 )
275 ;;;
276 (defun mouse-select-line-end (arg)
277 (setq mouse::last-point -1)
278 (when mouse::line-zone (delete-zone mouse::line-zone))
279 (pop-event 'motion)
280 )
281 ;;;
282 (defun mouse-select-line-update (type value scr)
283 (let*
284 (
285 y
286 pos
287 bol
288 (out-of-bounds t)
289 (epoch::event-handler-abort nil)
290 (w-edges (window-pixedges (selected-window)))
291 (top (elt w-edges 1))
292 (bottom (- (elt w-edges 4) top 1))
293 max-vscroll
294 )
295 (while
296 (and
297 out-of-bounds
298 (setq pos (query-pointer))
299 (/= 0 (logand mouse-any-mask (elt pos 2)))
300 )
301 ;;convert to window relative co-ordinates
302 (setq y (- (elt pos 1) top))
303 (setq out-of-bounds (not (and (<= 0 y) (<= y bottom))))
304
305 ;; Scrolling hard, because of possibly shrink-wrapped windows.
306 ;; set max-vscroll to be the most we could scroll down and not have
307 ;; empty lines at the bottom
308 (save-excursion
309 (move-to-window-line bottom) ;go to the last line in the window
310 (setq max-vscroll
311 (- vertical-drag-inc (forward-line vertical-drag-inc))
312 )
313 (if (and (> max-vscroll 0) (eobp) (= 0 (current-column)))
314 (decf max-vscroll)
315 )
316 )
317 (condition-case errno
318 (progn
319 (if (< y 0) (scroll-down vertical-drag-inc))
320 (if (> y bottom) (scroll-up (min max-vscroll vertical-drag-inc)))
321 )
322 ;; CONDITIONS
323 (error) ;nothing, just want to catch it
324 )
325 (setq y (max 0 (min bottom y)))
326
327 ;;move to the new point
328 (move-to-window-line y)
329 (beginning-of-line) (setq bol (point))
330 (end-of-line)
331 (when (/= mouse::last-point (point))
332 (move-zone mouse::line-zone bol (point))
333 (epoch::redisplay-screen)
334 )
335 (setq mouse::last-point (point))
336 )
337 )
338 )
339 ;;; --------------------------------------------------------------------------
340 ;; Stolen from AMC
341 (defun mouse::buffer-line (marg)
342 "Show the line number and buffer of the mouse EVENT"
343 ;; marg is (point buffer window screen)
344 ;; Pop over to the clicked buffer
345 (save-excursion (set-buffer (cadr marg))
346 ;; Figure out how far down the mouse point is
347 (let ((n (count-lines (point-min) (car marg))))
348 ;; display it. Include the buffer name for good measure.
349 (message (format "Line %d in %s" n (buffer-name (cadr marg))))
350 )))
351
352 ;; Blow out of any current isearch
353 (defun abort-isearch () "Abort any isearch in progress."
354 (condition-case err
355 (throw 'search-done t)
356 (no-catch nil)))
357 ;;; --------------------------------------------------------------------------
358 ;;; install all our various handlers
359 (global-set-mouse mouse-left mouse-down 'start-mouse-drag)
360 (global-set-mouse mouse-left mouse-shift 'mouse::buffer-line)
361 (global-set-mouse mouse-left mouse-up 'end-mouse-drag)
362 (global-set-mouse mouse-right mouse-down 'extend-mouse-drag)
363 (global-set-mouse mouse-right mouse-up 'end-mouse-drag)
364 (global-set-mouse mouse-middle mouse-down 'mouse::paste-cut-buffer)
365
366
367 (defun mouse-set-spot (arg)
368 "Set point at mouse. With double-click, set mark there as well.
369 Blinks matching paren if sitting after one. Intended to be bound
370 to a window down button."
371 (start-mouse-drag arg)
372 (let ((buf (current-buffer))
373 (p (point)))
374 (mouse::set-point arg)
375 (if (and (equal p (point))
376 (equal buf (current-buffer)))
377 (if (and (= mouse::clicks 1)
378 (not (eq (mark) (point))))
379 (push-mark))
380 (setq mouse::clicks 0))
381 (if (eq (char-syntax (preceding-char)) ?\))
382 (blink-matching-open)))
383 (abort-isearch))
384
385