[comp.emacs] mouse-driven info for Epoch 3.2beta

carlton@mitre.org (David Carlton) (07/24/90)

Here are some files for adding mouse/button support to info-mode in
Epoch 3.2beta.  They're the first thing that I ever wrote that was
Epoch-specific, so don't get mad at me if I didn't do everything quite
the right way :-)  What they is adds buttons to various important
places on the screen (menus, cross-references, next/previous/up);
clicking on them with the right mouse button gets you to the node
referred to.

It can slow down things, and I don't really understand why Epoch gets
slowed down by this as much as it does.  In particular, whenever I
enter a node with lots of menu items (e.g. the top of the Emacs Lisp
Manual), everything that I do from then on seems slowed down.  I can
understand it taking a while to parse that node (and for that matter
I'm running on a rather slow computer), but why would my entering that
node cause reading mail with epoch to go slower as well?  And the
effect seems to linger even after I've gone to another info file and
that one is no longer in the buffer.  So I'm confused about this;
maybe something isn't being garbage collected right?

Also, some more functionality should probably added, like buttons for
Next, Previous, Up, scroll forward, and scroll back.  (Yes, the first
3 exist; but they move around.)  This certainly wouldn't be at all
hard to do; the only question is what the layout should be.  Should it
be done via GWM?  (which i haven't converted to yet...)  Should I open
up another (small) buffer (or even screen?) for them?  etc...

On a totally unrelated note, I believe that somebody asked a while
back how (s)he could specify the geometry of the initial screen
without having all subsequent screens show up in the same place.  (It
was either asked here or on the Epoch mailing list.)  My answer to that
is to put the line

(setq epoch::screen-properties (cons '(geometry . "80x48")
				     epoch::screen-properties))

in my .emacs.  (Of course, only do this after you've made sure you are
running epoch; and you can replace "80x48" with whatever size you
want.)

So: here is a patch file for info.el and another file called
infobuttons.el which will give you everything you need to have a
mouse-driven info.  Make sure that you put the newer info.el in your
load path somewhere before /usr/local/lib/emacs/lisp (or wherever the
standard one is.)  Enjoy.

david carlton
carlton@linus.mitre.org


#! /bin/sh
# This is a shell archive, meaning:
# 1. Remove everything above the #! /bin/sh line.
# 2. Save the resulting text in a file.
# 3. Execute the file with /bin/sh (not csh) to create the files:
#	info.patch
#	infobuttons.el
# This archive created: Mon Jul 23 11:33:01 1990
export PATH; PATH=/bin:$PATH
if test -f 'info.patch'
then
	echo shar: will not over-write existing file "'info.patch'"
else
cat << \SHAR_EOF > 'info.patch'
*** info.el	Mon Jul 23 10:57:54 1990
--- epochinfo.el	Mon Jul 23 10:56:33 1990
***************
*** 19,24 ****
--- 19,25 ----
  ;; and this notice must be preserved on all copies.
  
  (provide 'info)
+ (require 'infobuttons)
  
  (defvar Info-history nil
    "List of info nodes user has visited.
***************
*** 53,59 ****
    (interactive)
    (if (get-buffer "*info*")
        (switch-to-buffer "*info*")
!     (Info-directory)))
  
  ;; Go to an info node specified as separate filename and nodename.
  ;; no-going-back is non-nil if recovering from an error in this function;
--- 54,62 ----
    (interactive)
    (if (get-buffer "*info*")
        (switch-to-buffer "*info*")
!     (progn
!       (Info-directory)
!       (Info-setup-mouse-map))))
  
  ;; Go to an info node specified as separate filename and nodename.
  ;; no-going-back is non-nil if recovering from an error in this function;
***************
*** 167,172 ****
--- 170,176 ----
  	  (setq Info-history (cdr Info-history))
  	  (Info-find-node (nth 0 hist) (nth 1 hist) t)
  	  (goto-char (nth 2 hist)))))
+   (Info-setup-buttons)
    (goto-char (point-min)))
  
  (defun Info-read-subfile (nodepos)
SHAR_EOF
fi # end of overwriting check
if test -f 'infobuttons.el'
then
	echo shar: will not over-write existing file "'infobuttons.el'"
else
cat << \SHAR_EOF > 'infobuttons.el'
;; Code to add mouse/button support for info in Epoch 3.2beta.
;; Written by david carlton, carlton@linus.mitre.org or 
;; carlton@husc9.harvard.edu.  Enjoy.

(provide 'infobuttons)

(defvar Info-button-attribute (reserve-attribute))
(defvar Info-mouse-map nil
  "Mousemap for Info buttons")
(if (not Info-mouse-map)
    (progn
      (setq Info-mouse-map (create-mouse-map mouse::global-map))
      (define-mouse Info-mouse-map mouse-right mouse-down
	'Info-menu-mouse-item)))

(defun Info-setup-mouse-map ()
  (use-local-mouse-map Info-mouse-map)
  (local-set-mouse mouse-right mouse-down 'Info-menu-mouse-item))

(defun Info-setup-buttons ()
  "Setup all buttons in an info-node's menu"
  (interactive)
  (catch 'boogie
    (let (p1st
	  p2nd
	  name
	  i)
      (save-excursion
        ;;; setup menu buttons
	(goto-char (point-min))
	(if (search-forward "\n* menu:" nil t)
	    (while (re-search-forward "\n\\* \\([^:\t\n]*\\):" nil t)
	      (beginning-of-line)
	      (setq p1st (point-marker))
	      (forward-char 1)
	      (setq p2nd (point-marker))
	      (setq name (Info-extract-menu-item
			  (buffer-substring (match-beginning 1)
					    (match-end 1))))
	      (if (not (button-at p1st))
		  (add-button p1st p2nd Info-button-attribute name)
		(throw 'boogie '()))))
        ;;; setup header buttons
	(Info-setup-mouse-pointer "Next")
	(Info-setup-mouse-pointer "Prev")
	(Info-setup-mouse-pointer "Up")
        ;;; setup cross-references
	(goto-char (point-min))
	(while (re-search-forward "\\*note[ \n\t]*\\([^:]*\\):" nil t)
	  (save-excursion
	    (goto-char (match-beginning 0))
	    (setq p1st (point-marker))
	    (forward-char 5)
	    (setq p2nd (point-marker)))
	  (setq name (buffer-substring
		      (match-beginning 1)
		      (1- (point))))
	  (setq i 0)
	  (while (setq i (string-match "[ \n\t]+" name i))
	    (setq name (concat (substring name 0 i) " "
			       (substring name (match-end 0))))
	    (setq i (1+ i)))
	  (setq name (concat "\\*note " name))
	  (while (setq i (string-match " " name i))
	    (setq name (concat (substring name 0 i) "[ \t\n]+"
			       (substring name (1+ i))))
	    (setq i (+ i 6)))
	  (save-excursion
	    (goto-char p1st)
	    (re-search-forward name nil t)
	    (goto-char (+ (match-beginning 0) 5))
	    (setq name (Info-extract-menu-node-name
			"Bad format cross reference")))
	  (while (setq i (string-match "[ \t\n]+" name i))
	    (setq name (concat (substring name 0 i) " "
			       (substring name (match-end 0))))
	    (setq i (+ i 1)))
	  (if (not (button-at p1st))
	      (add-button p1st p2nd Info-button-attribute name)
	    (throw 'boogie '())))))))

(defun Info-setup-mouse-pointer (where)
  (let ((p1st '())
	(p2nd '())
	(name '()))
    (save-excursion
      (goto-char (point-min))
      (forward-line 1)
      (if (re-search-backward (concat where ":") nil t)
	  (progn
	    (setq p1st (point-marker))
	    (goto-char (match-end 0))
	    (setq p2nd (point-marker))
	    (setq name (Info-following-node-name))
	    (if (not (button-at p1st))
		(add-button p1st p2nd Info-button-attribute name)))))))

(defun Info-menu-mouse-item (mouse-data)
  (let ((button (button-at (car mouse-data))))
    (if (and button
	     (equal (button-attribute button) Info-button-attribute))
	(Info-goto-node (button-data button)))))
SHAR_EOF
fi # end of overwriting check
#	End of shell archive
exit 0