Mercurial > hg > xemacs
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 |
