weiner@novavax.UUCP (Bob Weiner) (04/29/89)
;;!emacs ;; ;; FILE: smart-info.el ;; SUMMARY: Walks through Info networks using one key ;; USAGE: GNU Emacs Lisp Library, functions called by smart-key.el ;; ;; AUTHOR: Bob Weiner, Applied Research, Motorola, Inc., (407)738-2087 ;; E-MAIL: USENET: weiner@novavax.UUCP ;; ORIG-DATE: 04-Apr-89 ;; LAST-MOD: 28-Apr-89 at 00:32:34 by Bob Weiner ;; ;; Smart-info package for GNU Emacs. ;; Copyright (C) 1989 Bob Weiner and Free Software Foundation, Inc. ;; Available for use and distribution under the same terms as GNU Emacs. ;; ;; This file is not yet part of GNU Emacs. ;; ;; Bob Weiner, 03/06/89 ;; Added 'smart-info-meta' command. ;; ;; Bob Weiner, 03/06/89 ;; Changed so that if user hits key at the end of or past the end of the ;; current line, smart-info scrolls up a screen; smart-info-meta scrolls ;; down. This does not apply when the last line of a node is clicked on. ;; ;; Bob Weiner, 03/06/89 ;; Changed so that smart-info and smart-info-meta are called from smart-key.el. ;; Removed mouse-non-info-command and mouse-meta-non-info-command-variables. ;; ;; DESCRIPTION: ;;; ;;; This code is machine independent. ;;; ;;; To install: ;;; ;;; See smart-key.el ;;; ;; DESCRIP-END. (defun smart-info () "Walks through Info documentation networks using one key or mouse key. If key is pressed within: (1) an Info Menu or Note, the desired node is found; (2) the Up,Next,or Previous entries of a Node Header (first line), the desired node is found; (3) the File entry of a Node Header (first line), the 'Top' node within that file is found; (4) at the end of the current node, the Next node is found. (5) anywhere else (e.g. at the end of a line), the current node entry is scrolled up one screen Returns t if key is pressed within an Info Node Header, Note (cross-reference), or a Menu; otherwise returns nil." (interactive) (cond ;; ;; If at end of node, go to next node ;; ((last-line-p) (Info-next)) ;; ;; If at end of line, scroll forward a screen ;; ((eolp) (scroll-up-eol)) ((Info-handle-in-node-hdr)) ((Info-handle-in-note)) ((Info-handle-in-menu)) ;; ;; If nothing else scroll forward a screen. ;; ((scroll-up-eol)))) (defun smart-info-meta () "Walks through Info documentation networks using one meta-key or mouse meta-key. If meta-key is pressed within: (1) an Info Menu or Note, the desired node is found; (2) the Up,Next,or Previous entries of a Node Header (first line), the last node in the history list is found; (3) the File entry of a Node Header (first line), the 'DIR' root-level node is found; (4) at the end of the current node, the Previous node is found. (5) anywhere else (e.g. at the end of a line), the current node entry is scrolled down one screen Returns t if meta-key is pressed within an Info Node Header, Note (cross-reference), or a Menu; otherwise returns nil." (interactive) (cond ;; ;; If at end of node, go to previous node ;; ((last-line-p) (Info-prev)) ;; ;; If at end of line, scroll backward a screen ;; ((eolp) (scroll-down-eol)) ((Info-handle-in-node-hdr-meta)) ((Info-handle-in-note)) ((Info-handle-in-menu)) ;; ;; If anywhere else, scroll backward a screen. ;; ((scroll-down-eol)))) (defun Info-handle-in-node-hdr () "If within an Info node header, move to <FILE>Top, <Up>, <Previous>, or <Next> node, depending on which label point is on, and return t. Otherwise, return nil." ;; ;; Test if on 1st line of node, i.e. node header ;; (if (not (first-line-p)) nil (let ((nodename "Top") (filep nil)) (save-excursion (if (and (re-search-forward "[:, \t\n]" nil t) (re-search-backward "\\(File\\|Node\\|Up\\|Prev\\|Previous\\|Next\\)[: \t]" nil t)) (progn (setq filep (string-equal "file" (downcase (buffer-substring (match-beginning 1) (match-end 1))))) (if (re-search-forward (concat ":[ \n]\\([^,.\t\n" (if filep " ") "]*\\)") nil t) (setq nodename (buffer-substring (match-beginning 1) (match-end 1))))) (error "Node header not found."))) (if filep (setq nodename (concat "(" nodename ")" "Top"))) (Info-goto-node nodename) t))) (defun Info-handle-in-node-hdr-meta () "If within an Info node header when the 'smart-info-meta' command is executed, when within the <FILE> header go to the DIR top-level node. When within any other header (<Up>, <Previous>, or <Next>) go to last node from history list. Return t if in Info node header. Otherwise return nil." ;; ;; Test if on 1st line of node, i.e. node header ;; (if (not (first-line-p)) nil (save-excursion (if (and (re-search-forward "[:, \t\n]" nil t) (re-search-backward "\\(File\\|Node\\|Up\\|Prev\\|Previous\\|Next\\)[: \t]" nil t) ) ;; If in <FILE> hdr (progn (if (string-equal "file" (downcase (buffer-substring (match-beginning 1) (match-end 1)))) (Info-directory) (Info-last)) t) (error "Node header not found.") nil)))) (defun Info-handle-in-note () "If point is within the first line of an Info note (cross-reference), follow cross-reference and return t; otherwise return nil." (let ((note-name nil) (bol nil)) (save-excursion (if (re-search-forward "[:.\n]" nil t) (progn (save-excursion (beginning-of-line) (setq bol (point))) (if (re-search-backward "\*Note[ \t\n]+\\([^:]*\\):" bol t) (setq note-name (buffer-substring (match-beginning 1) (match-end 1))))))) (if (not note-name) nil (Info-follow-reference note-name) t))) (defun Info-handle-in-menu () "If point is within an Info menu entry, go to node referenced by entry and return t; otherwise return nil." ;; ;; Test if there is a menu in this node ;; (let ((in-menu nil) (curr-point (point))) (save-excursion (goto-char (point-min)) (setq in-menu (and (search-forward "\n* menu:" nil t) (< (point) curr-point)))) (if (not in-menu) nil (forward-char) ; Pass '*' char if point is in front of (if (search-backward "\n*" nil t) (progn (forward-char 2) (Info-goto-node (Info-extract-menu-node-name)))) t))) (provide 'smart-info) -- Bob Weiner, Motorola, Inc., USENET: ...!gatech!uflorida!novavax!weiner (407) 738-2087