home *** CD-ROM | disk | FTP | other *** search
- ;;; macmouse.el (Version: 2.0)
-
- ;;; Copyright (C) Gregory S. Lauer (glauer@bbn), 1985.
- ;;; Please send suggestions and corrections to the above address.
- ;;;
- ;;; This file contains macmouse, a GNU Emacs mouse package for UW.
-
-
- ;;
- ;; GNU Emacs is distributed in the hope that it will be useful,
- ;; but without any warranty. No author or distributor
- ;; accepts responsibility to anyone for the consequences of using it
- ;; or for whether it serves any particular purpose or works at all,
- ;; unless he says so in writing.
-
- ;; Everyone is granted permission to copy, modify and redistribute
- ;; GNU Emacs, but only under the conditions described in the
- ;; document "GNU Emacs copying permission notice". An exact copy
- ;; of the document is supposed to have been given to you along with
- ;; GNU Emacs so that you can know how you may redistribute it all.
- ;; It should be in a file named COPYING. Among other things, the
- ;; copyright notice and this notice must be preserved on all copies.
-
-
- ;;; Original version for Gosling emacs by Chris Kent, Purdue University 1985.
- ;;; Modified by Gregory Lauer, BBN, Novemeber 1985.
- ;
- ;
- ;
- ; Macmouse provides the following features:
- ; Up or down mouse button in a window selects that window
- ;
- ; A scroll bar/thumbing area for each window with the following features:
- ; the mode lines are horizontal scroll bars
- ; (running from rightmost column to under leftmost column)
- ; the unused right window bar and the dividing lines between
- ; windows are vertical scroll bars
- ; (running from top of window THRU modeline
- ; for vertical scroll bars:
- ; click at line 1 does previous page
- ; click at last line does next page
- ; click anywhere else "thumbs" to the relative portion of the buffer.
- ; shift-click at line 1 scrolls one line down
- ; shift-click at last line scrolls one line up
- ; shift-click elsewhere moves line to top of window
- ; option-shift-click elsewhere moves line to bottom of window
- ; for horizontal scroll bars:
- ; click at column 1 does scroll right one window width
- ; click at last column does scroll left one window width
- ; click anywhere else moves to that "percent" of the buffer width
- ; shift-click at column 1 scrolls one column right
- ; shift-click at last column scrolls one column left
- ; shift-click elsewhere moves column to right of window
- ; option-shift-click elsewhere moves column to left of window
- ;
- ; There is also basic positioning and kill-buffer support:
- ; click in a buffer moves dot there and selects that buffer
- ; drag copies the dragged region to the kill buffer
- ; shift-drag deletes the dragged region to the kill buffer
- ;
- ; It is possible to use the scrolling and thumbing area to make the region
- ; larger than a single screen; just click, scroll, release. Make sure
- ; that the last scroll is just a down event; the up must be in the buffer.
- ; The last mouse position is remembered for each different buffer (not
- ; window), and thus you can start a drag in one buffer, select another,
- ; go back to the first buffer, etc.
- ;
- ; option-click yanks from the kill buffer
- ; option-shift-click similarly yanks from a named buffer.
- ;
-
- (defconst mouse-max-x 95 "Maximum UW column returned on mouse click")
- (defconst mouse-max-y 95 "Maximum UW row returned on mouse click")
-
- (make-variable-buffer-local 'mouse-last-x) ; x of last event
- (set-default 'mouse-last-x 0)
-
- (make-variable-buffer-local 'mouse-last-y) ; y of last event
- (set-default 'mouse-last-y 0)
-
- (make-variable-buffer-local 'mouse-last-b) ; buttons at last event
- (set-default 'mouse-last-b 0)
-
- (make-variable-buffer-local 'mouse-last-dot) ; dot after last event
- (set-default 'mouse-last-dot 0)
-
- (make-variable-buffer-local 'scrolling-p)
- (set-default 'scrolling-p nil)
-
- (defun move-mac-cursor ()
- (interactive)
- (let (savest b x y up down lock shift option command)
- (setq savest stack-trace-on-error)
- (setq stack-trace-on-error nil)
- ; decode everything
- (setq y (- (read-char) 32))
- (setq x (- (read-char) 32))
- (setq b (- (read-char) 32))
- (setq command (< 0 (logand b 1))) ; command key
- (setq shift (< 0 (logand b 2))) ; shift
- (setq lock (< 0 (logand b 4))) ; caps-lock
- (setq option (< 0 (logand b 8))) ; option
- (setq down (< 0 (logand b 16))) ; mouse down
- (setq up (< 0 (logand b 32))) ; mouse up
- (condition-case ()
- (progn
- (select-window-containing-x-and-y x y) ; side-effect sets scrolling-p
- (if scrolling-p
- (mouse-scroll-region b x y)
- (progn
- (move-to-window-x-y x y) ; move cursor to mouse-dot always
- (if down (setq mouse-last-dot (dot)))
- (mouse-edit-action))))
- (error (message "Click not in selectable window")
- (sit-for 1)
- (message "")))
- (setq stack-trace-on-error savest)
- (if down
- (progn
- (setq mouse-last-x x)
- (setq mouse-last-y y)
- (setq mouse-last-b b))
- (progn
- (setq mouse-last-x 0)
- (setq mouse-last-y 0)
- (setq mouse-last-b 0)))))
-
- (defun mouse-edit-action ()
- ;marking and editing actions on buttons:
- ; if no movement, nothing.
- ; if movement, save mouse-last-dot,
- ; and edit.
- ; editing (on upstrokes):
- ; unmodified, copy to kill buffer.
- ; SHIFTed, delete (cut) to kill buffer.
- ;
- ; option-click yanks from kill buffer;
- ; shift-option-click from named buffer.
- (let ((fun (get 'mouse-function b)))
- (if fun (apply fun nil))))
-
-
- ; individual button bindings
- ; generally will only need up mouse button: mouse-last-dot
- ; is saved automatically on down mouse button
-
- ; only need to define functions for keys that get used
-
- (put 'mouse-function 32 ; up
- '(lambda ()
- (if (and (not (mouse-click-p))
- (not scrolling-p))
- (copy-region-as-kill (dot) mouse-last-dot))))
-
- (put 'mouse-function 34 ; up/shift
- '(lambda ()
- (if (and (not (mouse-click-p))
- (not scrolling-p))
- (kill-region (dot) mouse-last-dot))))
-
- (put 'mouse-function 40 ; up/option
- '(lambda ()
- (if (mouse-click-p)
- (progn
- (yank)
- (exchange-dot-and-mark)))))
-
- (put 'mouse-function 42
- '(lambda () ; up/option/shift
- (if (mouse-click-p)
- (insert-buffer (read-buffer "Insert contents of buffer: ")))))
-
- (defun mouse-click-p ()
- (= (dot) mouse-last-dot))
-
- (defun set-window-boundaries ()
- (let ((edges (window-edges)))
- (setq xl (1+ (car edges)))
- (setq yt (1+ (car (cdr edges))))
- (let ((temp (car (cdr (cdr edges)))))
- (setq xr (if (= (screen-width) temp) mouse-max-x temp)))
- (let ((temp (car (cdr (cdr (cdr edges))))))
- (setq yb (if (= (screen-height) temp) mouse-max-y temp )))))
-
- (defun select-window-containing-x-and-y (x y)
- (let ((starting-window (selected-window)))
- (set-window-boundaries)
- (while (not (point-in-window x y))
- (other-window 1)
- (if (eq (selected-window) starting-window)
- (error nil)
- (set-window-boundaries)))
- (if (or (= x xr) (= y yb))
- (setq scrolling-p t)
- (setq scrolling-p nil))))
-
- (defun point-in-window (x y)
- (and (<= xl x)(<= x xr)(<= yt y)(<= y yb)))
-
- (defun move-to-window-x-y (x y)
- (move-to-window-line (- y yt))
- (move-to-window-column (- x xl)))
-
- (defun move-to-window-column (x)
- (move-to-column (+ (max 0 (- (window-hscroll) 1)) x)))
-
- (defun mouse-scroll-region (b x y)
- (if down
- (if shift
- (do-lines b x y)
- (do-pages b x y)))
- (if (and up
- (or (/= x mouse-last-x)
- (/= y mouse-last-y)))
- (if shift
- (do-lines b x y)
- (do-pages b x y))))
-
- (defun do-lines (b x y) ; fine control over lines
- (if (= x xr)
- (cond ((= y yt)(scroll-down 1))
- ((= y yb)(scroll-up 1))
- (t (if option
- (scroll-down (- yb y 1))
- (scroll-up (- y yt))))))
- (if (and (= y yb) (/= x xr))
- (cond ((<= x xl)(scroll-right 1))
- ((>= x (1- xr))(scroll-left 1))
- (t (if option
- (move-column-right x)
- (move-column-left x))))))
-
- (defun move-column-left (x) ;need to mess about a bit because
- (scroll-left ;first scroll left of 1 just writes
- (if (= (window-hscroll) 0) ;a column of $s in column 1
- (- x xl)
- (- x xl 1))))
-
- (defun move-column-right (x)
- (scroll-right (- xr x 2)))
-
-
- (defun do-pages (b x y) ; large motions via pages and thumbing
- (if (= x xr)
- (cond ((= y yt)(scroll-down nil))
- ((= y yb)(scroll-up nil))
- (t (goto-percent (/ (* (- y yt 1) 100)
- (- yb yt 2))))))
- (if (and (= y yb)(/= x xr))
- (cond ((<= x xl)(scroll-right (- (window-width)
- next-screen-context-lines)))
- ((>= x (1- xr))(scroll-left (- (window-width)
- next-screen-context-lines)))
- (t (goto-horizontal-percent (/ (* (- x xl 1) 100)
- (- xr xl 2)))))))
-
- (defun goto-percent (p)
- (goto-char (/ (* (- (dot-max) (dot-min)) p) 100)))
-
- (defun goto-horizontal-percent (p) ;try to put this percent of columns
- (let ((window-offset (window-hscroll));in the center column of the window
- delta) ;unless that would move the first or
- (setq delta ;last column past the window edge
- (- window-offset
- (min (max 0 (- (/ (* (screen-width) p) 100)
- (/ (- xr xl) 2)))
- (- (screen-width) (- xr xl)))))
- (scroll-right delta)))
-
-
- (global-set-key "\em" 'move-mac-cursor)
-