diff 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
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/shared/motion4.el	Mon Feb 08 11:44:37 2021 +0000
@@ -0,0 +1,385 @@
+;;; Copyright (C) 1991 Christopher J. Love
+;;;
+;;; This file is for use with Epoch, a modified version of GNU Emacs.
+;;; Requires Epoch 4.0 or later.
+;;;
+;;; This code is distributed in the hope that it will be useful,
+;;; bute WITHOUT ANY WARRANTY. No author or distributor accepts
+;;; responsibility to anyone for the consequences of using this code
+;;; or for whether it serves any particular purpose or works at all,
+;;; unless explicitly stated in a written agreement.
+;;;
+;;; Everyone is granted permission to copy, modify and redistribute
+;;; this code, but only under the conditions described in the
+;;; GNU Emacs General Public License, except the original author nor his
+;;; agents are bound by the License in their use of this code.
+;;; (These special rights for the author in no way restrict the rights of
+;;;  others given in the License or this prologue)
+;;; A copy of this license is supposed to have been given to you along
+;;; with Epoch so you can know your rights and responsibilities. 
+;;; It should be in a file named COPYING.  Among other things, the
+;;; copyright notice and this notice must be preserved on all copies. 
+;;;
+;;; $Revision: 1.2 $
+;;; $Source: /home/user5/ht/emacs/shared/RCS/motion4.el,v $
+;;; $Date: 1992/03/18 21:44:10 $
+;;; $Author: ht $
+;;;
+;;; motion.el - provide draggin/hi-lighting of primary selection
+;;;
+;;; Original version by Alan Carroll
+;;; Epoch 4.0 modifications by Chris Love
+;;; Abort-isearch and other ideas from Ken Laprade and others.
+;;;
+(provide 'motion)
+(redisplay-screen) ; fix epoch4.0a race bug?
+(require 'zone)
+(require 'mouse)
+
+;;; ------------------------------------------------------------------------
+;;; Interface values
+(defvar horizontal-drag-inc 5
+  "Number of columns to scroll when the pointer is to the left or right of the window")
+(defvar vertical-drag-inc 2
+  "Number of lines to scroll when the pointer is above or below the edge of the window")
+
+(defvar mouse::downp nil "State variable for mouse dragging internals")
+(defvar mouse::last-point -1 "Last location of a motion event")
+
+(setq epoch::zones-modify-buffer nil)
+(defvar motion::style nil "style used by drag zones")
+
+(defvar drag-zone nil
+  "Epoch zone to be used for hilighting selected text region."
+)
+(setq-default drag-zone nil)
+(setq-default mouse-down-marker nil)
+
+;;; ------------------------------------------------------------------------
+;;; Set window-setup-hook to call motion::init(), which sets default
+;;; style for zone dragging.  Default style is underlining; can be changed
+;;; in .emacs file.
+(epoch-add-setup-hook 'motion::init)
+
+(defun motion::init ()
+  (and (not motion::style) (setq motion::style (make-style)))
+  (set-style-foreground motion::style (foreground))
+  (set-style-background motion::style (background))
+  (set-style-underline motion::style (foreground))
+  ;; enable the handler
+  (push-event 'motion 'motion::handler)
+  ;; set up hints on all the current screens
+  (dolist (s (screen-list t)) (epoch::set-motion-hints t s))
+  ;; enable hints on future screens
+  (push '(motion-hints t) epoch::screen-properties)
+  )
+
+;;; ------------------------------------------------------------------------
+(defun set-mouse-marker (&optional location)
+  (if (null mouse-down-marker)
+    (setq mouse-down-marker (make-marker))
+  )
+  (set-marker mouse-down-marker (or location (point)))
+)
+
+;;; --------------------------------------------------------------------------
+;;; Functions to provide dragging & hilighting.
+;;; arg is a list of ( POINT BUFFER WINDOW SCREEN )
+(defun end-mouse-drag (arg)
+  (setq mouse::last-point -1)		;always do this cleanup
+  (when mouse::downp
+    (setq mouse::downp nil)
+    (mouse::copy-zone drag-zone)
+    (let (
+	(s (and drag-zone (zone-start drag-zone)))
+	(e (and drag-zone (zone-end drag-zone)))
+      )
+      (if (null s) (setq s 1))
+      (if (null e) (setq e 1))
+      (if (zonep drag-zone)
+	(if (<= (point) s)
+	  (progn
+	    (push-mark e t)
+	    (goto-char s)
+	  )
+	;; ELSE point is past drag zone start
+	  (progn
+	    (push-mark s t)
+	    (goto-char e)
+	  )
+	)
+      )
+    )
+  )
+)
+
+(defun start-mouse-drag (arg)
+  (when arg
+    (setq mouse::downp 'start)
+;    (message "%s" arg)
+    (mouse::set-point arg)
+    (abort-isearch)
+    (set-mouse-marker)
+    (setq mouse::last-point (point))
+    (if drag-zone
+      (progn
+	(message "ddz")
+	(delete-zone drag-zone)
+	(setq drag-zone nil)
+	(redisplay-screen)
+      )
+    )
+  )
+)
+
+(defun extend-mouse-drag (arg)
+  (setq mouse::downp 'extend)
+  (let
+    (
+      (m1 (and drag-zone (zone-start drag-zone)))
+      (m2 (and drag-zone (zone-end drag-zone)))
+      (spot (car arg))			;point of the mouse click.
+    )
+    (if (null m1) (setq m1 0))
+    (if (null m2) (setq m2 0))
+    (cond
+      ((or (null drag-zone) (null mouse-down-marker))
+	(setq drag-zone (add-zone (point) spot motion::style) )
+	(set-zone-transient drag-zone t)
+	(set-mouse-marker)
+      )
+      ((<= spot m1)
+	(setq drag-zone (move-zone drag-zone spot m2) )
+	(set-mouse-marker m2)
+      )
+      ((>= spot m2)
+	(setq drag-zone (move-zone drag-zone m1 spot) )
+	(set-mouse-marker m1)
+      )
+      ((<= mouse-down-marker spot)
+	(setq drag-zone (move-zone drag-zone m1 spot) )
+	(set-mouse-marker m1)
+      )
+      (t
+	(setq drag-zone (move-zone drag-zone spot m2) )
+	(set-mouse-marker m2)
+      )
+    )
+    (epoch::redisplay-screen)
+    (setq mouse::last-point (point))
+  )
+)
+
+;;; ------------------------------------------------------------------------
+;;; Define the handler for dragging, etc.
+(defun motion::handler (type value scr)
+  (if (null mouse-down-marker) (set-mouse-marker))
+  (if (and (boundp 'mouse::downp) mouse::downp)
+    (mouse-sweep-update)
+  )
+)
+
+;;;
+(defun mouse-sweep-update()
+  (let*
+    (
+      drag-m1
+      drag-m2
+      pnt
+      pos
+      x
+      y
+      (w (selected-window))      
+      (out-of-bounds t)
+      (epoch::event-handler-abort nil)
+      (w-edges (window-pixedges w))
+      (left (car w-edges))
+      (top (elt w-edges 1))
+      (right (- (elt w-edges 2) left 1))
+      (bottom (- (elt w-edges 4) top 1))
+    )
+    (while
+      (and
+	out-of-bounds
+	(setq pos (query-pointer))
+	(/= 0 (logand mouse-any-mask (elt pos 2)))
+      )
+      ;;convert to window relative co-ordinates
+      (setq x (- (car pos) left))
+      (setq y (- (elt pos 1) top))
+      (setq out-of-bounds
+	(not (and (<= 0 y) (<= y bottom) (<= 0 x) (<= x right)))
+      )
+      ;; scrolling conditions
+      (condition-case errno
+	(progn
+	  (if (< y 0) (scroll-down vertical-drag-inc))
+	  (if (> y bottom) (scroll-up vertical-drag-inc))
+	)
+	(error )			;nothing, just catch it
+      )
+;; Disable horizontal scrolling.
+;      (if (< x left) (scroll-right horizontal-drag-inc))
+;      (if (> x right) (scroll-left horizontal-drag-inc))
+      (setq y (max 1 (min bottom y)))
+      (setq x (max 0 (min right x)))
+      (setq pnt (car (epoch::coords-to-point (+ x left) (+ y top))))
+      (when (/= mouse::last-point pnt)
+	    (if (> mouse-down-marker pnt)
+		(progn
+		  (setq drag-m1 pnt)
+		  (setq drag-m2 (marker-position mouse-down-marker))
+		  )
+	      (progn
+		(setq drag-m1 (marker-position mouse-down-marker))
+		(setq drag-m2 (1+ pnt))
+		)
+	      )
+	    ;; moved this in here so that zone won't get made if
+	    ;; only motion is jitter within a single character
+	    ;; this fixes a bunch of bogus (often empty)
+	    ;; entries in the kill ring
+	    (if drag-zone
+		(move-zone drag-zone drag-m1 drag-m2)
+	      (progn (setq drag-zone
+			   (add-zone drag-m1 drag-m2 motion::style )
+			   )
+		     (set-zone-transient drag-zone t)
+		     )
+	      )
+	    (redisplay-screen)
+	    )
+      (setq mouse::last-point pnt)
+    )
+  )
+)
+    
+;;; ------------------------------------------------------------------------
+;;; Code for selecting lines using motion events. Assumes that the line is
+;;; left unmarked on zone up
+(defvar mouse::line-zone nil "Zone for selected line")
+;;;
+(defun mouse-select-line-start (arg)
+  (mouse::set-point arg)		;go there
+  (setq mouse::last-point (point))
+  (let ( bol )
+    (save-excursion
+      (beginning-of-line)
+      (setq bol (point))
+      (end-of-line)
+      (setq mouse::line-zone (add-zone bol (point) motion::style))
+    )
+  )
+  (push-event 'motion 'mouse-select-line-update)
+)
+;;;
+(defun mouse-select-line-end (arg)
+  (setq mouse::last-point -1)
+  (when mouse::line-zone (delete-zone mouse::line-zone))
+  (pop-event 'motion)
+)
+;;;
+(defun mouse-select-line-update (type value scr)
+  (let*
+    (
+      y
+      pos
+      bol
+      (out-of-bounds t)
+      (epoch::event-handler-abort nil)
+      (w-edges (window-pixedges (selected-window)))
+      (top (elt w-edges 1))
+      (bottom (- (elt w-edges 4) top 1))
+      max-vscroll
+    )
+    (while
+      (and
+	out-of-bounds
+	(setq pos (query-pointer))
+	(/= 0 (logand mouse-any-mask (elt pos 2)))
+      )
+      ;;convert to window relative co-ordinates
+      (setq y (- (elt pos 1) top))
+      (setq out-of-bounds (not (and (<= 0 y) (<= y bottom))))
+
+      ;; Scrolling hard, because of possibly shrink-wrapped windows.
+      ;; set max-vscroll to be the most we could scroll down and not have
+      ;; empty lines at the bottom
+      (save-excursion
+	(move-to-window-line bottom)	;go to the last line in the window
+	(setq max-vscroll
+	  (- vertical-drag-inc (forward-line vertical-drag-inc))
+	)
+	(if (and (> max-vscroll 0) (eobp) (= 0 (current-column)))
+	  (decf max-vscroll)
+	)
+      )
+      (condition-case errno
+	(progn
+	  (if (< y 0) (scroll-down vertical-drag-inc))
+	  (if (> y bottom) (scroll-up (min max-vscroll vertical-drag-inc)))
+	)
+	;; CONDITIONS
+	(error)				;nothing, just want to catch it
+      )
+      (setq y (max 0 (min bottom y)))
+
+      ;;move to the new point
+      (move-to-window-line y)
+      (beginning-of-line) (setq bol (point))
+      (end-of-line)
+      (when (/= mouse::last-point (point))
+	(move-zone mouse::line-zone bol (point))
+	(epoch::redisplay-screen)
+      )
+      (setq mouse::last-point (point))
+    )
+  )
+)
+;;; --------------------------------------------------------------------------
+;; Stolen from AMC
+(defun mouse::buffer-line (marg)
+  "Show the line number and buffer of the mouse EVENT"
+  ;; marg is (point buffer window screen)
+  ;; Pop over to the clicked buffer
+  (save-excursion (set-buffer (cadr marg))
+    ;; Figure out how far down the mouse point is
+    (let ((n (count-lines (point-min) (car marg))))
+      ;; display it. Include the buffer name for good measure.
+      (message (format "Line %d in %s" n (buffer-name (cadr marg))))
+)))
+
+;; Blow out of any current isearch
+(defun abort-isearch () "Abort any isearch in progress."
+  (condition-case err
+      (throw 'search-done t)
+    (no-catch nil)))
+;;; --------------------------------------------------------------------------
+;;; install all our various handlers
+(global-set-mouse mouse-left mouse-down 'start-mouse-drag)
+(global-set-mouse mouse-left mouse-shift 'mouse::buffer-line)
+(global-set-mouse mouse-left mouse-up 'end-mouse-drag)
+(global-set-mouse mouse-right mouse-down 'extend-mouse-drag)
+(global-set-mouse mouse-right mouse-up 'end-mouse-drag)
+(global-set-mouse mouse-middle mouse-down 'mouse::paste-cut-buffer)
+
+
+(defun mouse-set-spot (arg)
+  "Set point at mouse.  With double-click, set mark there as well.
+Blinks matching paren if sitting after one.  Intended to be bound
+to a window down button."
+  (start-mouse-drag arg)
+  (let ((buf (current-buffer))
+        (p (point)))
+    (mouse::set-point arg)
+    (if (and (equal p (point))
+             (equal buf (current-buffer)))
+        (if (and (= mouse::clicks 1)
+                 (not (eq (mark) (point))))
+            (push-mark))
+      (setq mouse::clicks 0))
+    (if (eq (char-syntax (preceding-char)) ?\))
+          (blink-matching-open)))
+  (abort-isearch))
+
+