Annotation of 43BSD/contrib/emacs/lisp/info.el, revision 1.1

1.1     ! root        1: ;; Info package for Emacs  -- could use a "create node" feature.
        !             2: ;; Copyright (C) 1985 Richard M. Stallman.
        !             3: 
        !             4: ;; This file is part of GNU Emacs.
        !             5: 
        !             6: ;; GNU Emacs is distributed in the hope that it will be useful,
        !             7: ;; but WITHOUT ANY WARRANTY.  No author or distributor
        !             8: ;; accepts responsibility to anyone for the consequences of using it
        !             9: ;; or for whether it serves any particular purpose or works at all,
        !            10: ;; unless he says so in writing.  Refer to the GNU Emacs General Public
        !            11: ;; License for full details.
        !            12: 
        !            13: ;; Everyone is granted permission to copy, modify and redistribute
        !            14: ;; GNU Emacs, but only under the conditions described in the
        !            15: ;; GNU Emacs General Public License.   A copy of this license is
        !            16: ;; supposed to have been given to you along with GNU Emacs so you
        !            17: ;; can know your rights and responsibilities.  It should be in a
        !            18: ;; file named COPYING.  Among other things, the copyright notice
        !            19: ;; and this notice must be preserved on all copies.
        !            20: 
        !            21: 
        !            22: (defvar Info-history nil
        !            23:   "List of info nodes user has visited.
        !            24: Each element of list is a list (FILENAME NODENAME BUFFERPOS).")
        !            25: 
        !            26: (defvar Info-enable-edit nil
        !            27:   "Non-nil means the \\[Info-edit] command in Info can edit the current node.")
        !            28: 
        !            29: (defvar Info-enable-active-nodes t
        !            30:   "Non-nil allows Info to execute Lisp code associated with nodes.
        !            31: The Lisp code is executed when the node is selected.")
        !            32: 
        !            33: (defvar Info-directory nil
        !            34:   "Default directory for Info documentation files.")
        !            35: 
        !            36: (defvar Info-current-file nil
        !            37:   "Info file that Info is now looking at, or nil.")
        !            38: 
        !            39: (defvar Info-current-node nil
        !            40:   "Name of node that Info is now looking at, or nil.")
        !            41: 
        !            42: (defvar Info-tag-table-marker (make-marker)
        !            43:   "Marker pointing at beginning of current Info file's tag table.
        !            44: Marker points nowhere if file has no tag table.")
        !            45: 
        !            46: (defun info ()
        !            47:   "Create a buffer for Info, the documentation browser program."
        !            48:   (interactive)
        !            49:   (if (get-buffer "*info*")
        !            50:       (switch-to-buffer "*info*")
        !            51:     (Info-directory)))
        !            52: 
        !            53: ;; Go to an info node specified as separate filename and nodename.
        !            54: ;; no-going-back is non-nil if recovering from an error in this function;
        !            55: ;; it says do not attempt further (recursive) error recovery.
        !            56: (defun Info-find-node (filename nodename &optional no-going-back)
        !            57:   ;; Convert filename to lower case if not found as specified.
        !            58:   ;; Expand it.
        !            59:   (if filename
        !            60:       (let (temp)
        !            61:        (setq filename (substitute-in-file-name filename))
        !            62:        (setq temp (expand-file-name filename Info-directory))
        !            63:        (if (file-exists-p temp)
        !            64:            (setq filename temp)
        !            65:          (setq temp (expand-file-name (downcase filename) Info-directory))
        !            66:          (if (file-exists-p temp)
        !            67:              (setq filename temp)
        !            68:            (error "Info file %s does not exist"
        !            69:                   (expand-file-name filename Info-directory))))))
        !            70:   ;; Record the node we are leaving.
        !            71:   (if (and Info-current-file (not no-going-back))
        !            72:       (setq Info-history
        !            73:            (cons (list Info-current-file Info-current-node (point))
        !            74:                  Info-history)))
        !            75:   ;; Go into info buffer.
        !            76:   (switch-to-buffer "*info*")
        !            77:   (Info-mode)
        !            78:   (widen)
        !            79:   (setq Info-current-file nil Info-current-node nil)
        !            80:   (unwind-protect
        !            81:       (progn
        !            82:        ;; Switch files if necessary
        !            83:        (or (null filename)
        !            84:            (equal buffer-file-name filename)
        !            85:            (let ((buffer-read-only nil))
        !            86:              (erase-buffer)
        !            87:              (insert-file-contents filename t)
        !            88:              ;; See whether file has a tag table.  Record the location if yes.
        !            89:              (move-marker Info-tag-table-marker nil)
        !            90:              (goto-char (point-max))
        !            91:              (forward-line -8)
        !            92:              (if (search-forward "\^_\nEnd tag table\n" nil t)
        !            93:                  (progn
        !            94:                   (search-backward "\nTag table:\n")
        !            95:                   (move-marker Info-tag-table-marker (match-end 0))))))
        !            96:        (if (equal nodename "*")
        !            97:            (progn (setq Info-current-file buffer-file-name
        !            98:                         Info-current-node nodename)
        !            99:                   (Info-set-mode-line))
        !           100:          ;; Search file for a suitable node.
        !           101:          ;; First get advice from tag table if file has one.
        !           102:          (if (marker-position Info-tag-table-marker)
        !           103:              (progn
        !           104:                (goto-char Info-tag-table-marker)
        !           105:                (if (search-forward (concat "Node: " nodename "\177") nil t)
        !           106:                    (goto-char (max (point-min) (- (read (current-buffer)) 1000)))
        !           107:                  (error "No such node: %s" nodename)))
        !           108:            (goto-char (point-min)))
        !           109:          (let ((regexp (concat "Node: *" (regexp-quote nodename) " *[,\t\n]")))
        !           110:            (catch 'foo
        !           111:              (while (search-forward "\n\^_" nil t)
        !           112:                (forward-line 1)
        !           113:                (let ((beg (point)))
        !           114:                  (forward-line 1)
        !           115:                  (if (re-search-backward regexp beg t)
        !           116:                      (throw 'foo t))))
        !           117:              (error "No such node: %s" nodename)))
        !           118:          (Info-select-node)))
        !           119:     ;; If we did not finish finding the specified node,
        !           120:     ;; go back to the previous one.
        !           121:     (or Info-current-node no-going-back
        !           122:        (let ((hist (car Info-history)))
        !           123:          (setq Info-history (cdr Info-history))
        !           124:          (Info-find-node (nth 0 hist) (nth 1 hist) t)
        !           125:          (goto-char (nth 2 hist)))))
        !           126:   (goto-char (point-min)))
        !           127: 
        !           128: ;; Select the info node that point is in.
        !           129: (defun Info-select-node ()
        !           130:   (save-excursion
        !           131:    ;; Find beginning of node.
        !           132:    (search-backward "\n\^_")
        !           133:    (forward-line 2)
        !           134:    ;; Get nodename spelled as it is in the node.
        !           135:    (re-search-forward "Node:[ \t]*")
        !           136:    (setq Info-current-node
        !           137:         (buffer-substring (point)
        !           138:                           (progn
        !           139:                            (skip-chars-forward "^,\t\n")
        !           140:                            (point))))
        !           141:    (setq Info-current-file buffer-file-name)
        !           142:    (Info-set-mode-line)
        !           143:    ;; Find the end of it, and narrow.
        !           144:    (beginning-of-line)
        !           145:    (let (active-expression)
        !           146:      (narrow-to-region (point)
        !           147:                       (if (re-search-forward "\n[\^_\f]" nil t)
        !           148:                           (prog1
        !           149:                            (1- (point))
        !           150:                            (if (looking-at "[\n\^_\f]*execute: ")
        !           151:                                (progn
        !           152:                                  (goto-char (match-end 0))
        !           153:                                  (setq active-expression
        !           154:                                        (read (current-buffer))))))
        !           155:                         (point-max)))
        !           156:      (if Info-enable-active-nodes (eval active-expression)))))
        !           157: 
        !           158: (defun Info-set-mode-line ()
        !           159:   (setq mode-line-format
        !           160:        (concat 
        !           161:         "--%1*%1*-Info:  ("
        !           162:         (if buffer-file-name
        !           163:             (file-name-nondirectory buffer-file-name)
        !           164:           "")
        !           165:         ")"
        !           166:         (or Info-current-node "")
        !           167:         "   %M   %[(%m)%]----%3p-%-")))
        !           168: 
        !           169: ;; Go to an info node specified with a filename-and-nodename string
        !           170: ;; of the sort that is found in pointers in nodes.
        !           171: 
        !           172: (defun Info-goto-node (nodename)
        !           173:   "Go to info node named NAME.  Give just NODENAME or (FILENAME)NODENAME."
        !           174:   (interactive "sGoto node: ")
        !           175:   (let (filename)
        !           176:     (string-match "\\s *\\((\\s *\\([^\t)]*\\)\\s *)\\s *\\|\\)\\(.*\\)"
        !           177:                  nodename)
        !           178:     (setq filename (substring nodename (match-beginning 2) (match-end 2))
        !           179:          nodename (substring nodename (match-beginning 3) (match-end 3)))
        !           180:     (let ((trim (string-match "\\s *\\'" filename)))
        !           181:       (if trim (setq filename (substring filename 0 trim))))
        !           182:     (let ((trim (string-match "\\s *\\'" nodename)))
        !           183:       (if trim (setq nodename (substring nodename 0 trim))))
        !           184:     (Info-find-node (if (equal filename "") nil filename)
        !           185:                    (if (equal nodename "") "Top" nodename))))
        !           186: 
        !           187: (defun Info-tagify ()
        !           188:   "Create or update tag table of current info file."
        !           189:   (interactive)
        !           190:   ;; Save and restore point and restrictions.
        !           191:   ;; save-restrictions would not work
        !           192:   ;; because it records the old max relative to the end.
        !           193:   ;; We record it relative to the beginning.
        !           194:   (let ((omin (point-min))
        !           195:        (omax (point-max))
        !           196:        (opoint (point)))
        !           197:     (unwind-protect
        !           198:        (progn
        !           199:          (widen)
        !           200:          (goto-char (point-min))
        !           201:          (let ((regexp "Node:[ \t]*\\([^,\n\t]\\)*[,\t\n]")
        !           202:                (case-fold-search t)
        !           203:                list)
        !           204:            (while (search-forward "\n\^_" nil t)
        !           205:              (forward-line 1)
        !           206:              (let ((beg (point)))
        !           207:                (forward-line 1)
        !           208:                (if (re-search-backward regexp beg t)
        !           209:                    (setq list
        !           210:                          (cons (list (buffer-substring
        !           211:                                        (match-beginning 1)
        !           212:                                        (match-end 1))
        !           213:                                      beg)
        !           214:                                list)))))
        !           215:            (goto-char (point-max))
        !           216:            (forward-line -8)
        !           217:            (let ((buffer-read-only nil))
        !           218:              (if (search-forward "\^_\nEnd tag table\n" nil t)
        !           219:                  (let ((end (point)))
        !           220:                    (search-backward "\nTag table:\n")
        !           221:                    (beginning-of-line)
        !           222:                    (delete-region (point) end)))
        !           223:              (goto-char (point-max))
        !           224:              (insert "\^_\f\nTag table:\n")
        !           225:              (move-marker Info-tag-table-marker (point))
        !           226:              (setq list (nreverse list))
        !           227:              (while list
        !           228:                (insert "Node: " (car (car list)) ?\177)
        !           229:                (princ (car (cdr (car list))) (current-buffer))
        !           230:                (insert ?\n)
        !           231:                (setq list (cdr list)))
        !           232:              (insert "\^_\nEnd tag table\n"))))
        !           233:       (goto-char opoint)
        !           234:       (narrow-to-region omin (min omax (point-max))))))
        !           235: 
        !           236: (defun Info-validate ()
        !           237:   "Check that every node pointer points to an existing node."
        !           238:   (interactive)
        !           239:   (save-excursion
        !           240:     (save-restriction
        !           241:       (widen)
        !           242:       (goto-char (point-min))
        !           243:       (let ((allnodes '(("*")))
        !           244:            (regexp "Node:[ \t]*\\([^,\n\t]*\\)[,\t\n]")
        !           245:            (case-fold-search t)
        !           246:            (tags-losing nil)
        !           247:            (lossages ()))
        !           248:        (while (search-forward "\n\^_" nil t)
        !           249:          (forward-line 1)
        !           250:          (let ((beg (point)))
        !           251:            (forward-line 1)
        !           252:            (if (re-search-backward regexp beg t)
        !           253:                (setq allnodes
        !           254:                      (cons (list (downcase
        !           255:                                    (buffer-substring
        !           256:                                      (match-beginning 1)
        !           257:                                      (progn
        !           258:                                        (goto-char (match-end 1))
        !           259:                                        (skip-chars-backward " \t")
        !           260:                                        (point))))
        !           261:                                  (progn
        !           262:                                    (end-of-line)
        !           263:                                    (and (re-search-backward "prev[ious]*:"
        !           264:                                                             beg t)
        !           265:                                         (progn
        !           266:                                           (goto-char (match-end 0))
        !           267:                                           (downcase
        !           268:                                             (Info-following-node-name)))))
        !           269:                                  (point))
        !           270:                            allnodes)))))
        !           271:        (goto-char (point-min))
        !           272:        (while (search-forward "\n\^_" nil t)
        !           273:          (forward-line 1)
        !           274:          (let ((beg (point))
        !           275:                thisnode next)
        !           276:            (forward-line 1)
        !           277:            (if (re-search-backward regexp beg t)
        !           278:                (save-restriction
        !           279:                  (search-forward "\n\^_" nil 'move)
        !           280:                  (narrow-to-region beg (point))
        !           281:                  (setq thisnode (downcase
        !           282:                                   (buffer-substring
        !           283:                                     (match-beginning 1)
        !           284:                                     (progn
        !           285:                                       (goto-char (match-end 1))
        !           286:                                       (skip-chars-backward " \t")
        !           287:                                       (point)))))
        !           288:                  (end-of-line)
        !           289:                  (and (search-backward "next:" nil t)
        !           290:                       (setq next (Info-validate-node-name "Next"))
        !           291:                       (if (equal (car (cdr (assoc next allnodes)))
        !           292:                                  thisnode)
        !           293:                           ;; allow multiple `next' pointers to one node
        !           294:                           (let ((tem lossages))
        !           295:                             (while tem
        !           296:                               (if (and (equal (car (cdr (car tem)))
        !           297:                                               "Previous-pointer in Next")
        !           298:                                        (equal (car (cdr (cdr (car tem))))
        !           299:                                               next))
        !           300:                                   (setq lossages (delq (car tem) lossages)))
        !           301:                               (setq tem (cdr tem))))
        !           302:                         (setq lossages
        !           303:                               (cons (list thisnode
        !           304:                                           "Previous-pointer in Next"
        !           305:                                           next)
        !           306:                                     lossages))))
        !           307:                  (end-of-line)
        !           308:                  (if (search-backward "prev[ious]*:" nil t)
        !           309:                      (Info-validate-node-name "Previous"))
        !           310:                  (end-of-line)
        !           311:                  (if (search-backward "up:" nil t)
        !           312:                      (Info-validate-node-name "Up"))
        !           313:                  (if (search-forward "\n* Menu:" nil t)
        !           314:                      (while (search-forward "\n* " nil t)
        !           315:                        (Info-validate-node-name
        !           316:                         (concat "menu item "
        !           317:                                 (buffer-substring (point)
        !           318:                                                   (save-excursion
        !           319:                                                     (skip-chars-forward "^:")
        !           320:                                                     (point))))
        !           321:                         (Info-extract-menu-node-name))))
        !           322:                  (goto-char (point-min))
        !           323:                  (while (re-search-forward "\\*note[ \n]*[^:\t]*:" nil t)
        !           324:                    (goto-char (+ (match-beginning 0) 5))
        !           325:                    (skip-chars-forward " \n")
        !           326:                    (Info-validate-node-name
        !           327:                     (concat "reference "
        !           328:                             (buffer-substring (point)
        !           329:                                               (save-excursion
        !           330:                                                 (skip-chars-forward "^:")
        !           331:                                                 (point))))
        !           332:                     (Info-extract-menu-node-name "Bad format cross-reference")))))))
        !           333:        (setq tags-losing (not (Info-validate-tags-table)))
        !           334:        (if (or lossages tags-losing)
        !           335:            (with-output-to-temp-buffer " *problems in info file*"
        !           336:              (while lossages
        !           337:                (princ "In node \"")
        !           338:                (princ (car (car lossages)))
        !           339:                (princ "\", invalid ")
        !           340:                (let ((tem (nth 1 (car lossages))))
        !           341:                  (cond ((string-match "\n" tem)
        !           342:                         (princ (substring tem 0 (match-beginning 0)))
        !           343:                         (princ "..."))
        !           344:                        (t
        !           345:                         (princ tem))))
        !           346:                (princ ": ")
        !           347:                (let ((tem (nth 2 (car lossages))))
        !           348:                  (cond ((string-match "\n" tem)
        !           349:                         (princ (substring tem 0 (match-beginning 0)))
        !           350:                         (princ "..."))
        !           351:                        (t
        !           352:                         (princ tem))))
        !           353:                (terpri)
        !           354:                (setq lossages (cdr lossages)))
        !           355:              (if tags-losing (princ "\nTags table must be recomputed\n")))
        !           356:          (message "File appears valid"))))))
        !           357: 
        !           358: (defun Info-validate-node-name (kind &optional name)
        !           359:   (if name
        !           360:       nil
        !           361:     (goto-char (match-end 0))
        !           362:     (skip-chars-forward " \t")
        !           363:     (if (= (following-char) ?\()
        !           364:        nil
        !           365:       (setq name
        !           366:            (buffer-substring
        !           367:             (point)
        !           368:             (progn
        !           369:              (skip-chars-forward "^,\t\n")
        !           370:              (skip-chars-backward " ")
        !           371:              (point))))))
        !           372:   (if (null name)
        !           373:       nil
        !           374:     (setq name (downcase name))
        !           375:     (or (and (> (length name) 0) (= (aref name 0) ?\())
        !           376:        (assoc name allnodes)
        !           377:        (setq lossages
        !           378:              (cons (list thisnode kind name) lossages))))
        !           379:   name)
        !           380: 
        !           381: (defun Info-validate-tags-table ()
        !           382:   (goto-char (point-min))
        !           383:   (if (not (search-forward "\^_\nEnd tag table\n" nil t))
        !           384:       t
        !           385:     (not (catch 'losing
        !           386:           (let* ((end (match-beginning 0))
        !           387:                  (start (progn (search-backward "\nTag table:\n")
        !           388:                                (1- (match-end 0))))
        !           389:                  tem)
        !           390:             (setq tem allnodes)
        !           391:             (while tem
        !           392:               (goto-char start)
        !           393:               (or (equal (car (car tem)) "*")
        !           394:                   (search-forward (concat "Node: "
        !           395:                                           (car (car tem))
        !           396:                                           "\177")
        !           397:                                   end t)
        !           398:                   (throw 'losing 'x))
        !           399:               (setq tem (cdr tem)))
        !           400:             (goto-char (1+ start))
        !           401:             (while (looking-at ".*Node: \\(.*\\)\177\\([0-9]+\\)$")
        !           402:               (setq tem (assoc (buffer-substring
        !           403:                                  (match-beginning 1)
        !           404:                                  (match-end 1))
        !           405:                                allnodes))
        !           406:               (if (or (not tem)
        !           407:                       (< 1000 (progn
        !           408:                                 (goto-char (match-beginning 2))
        !           409:                                 (setq tem (- (car (cdr (cdr tem)))
        !           410:                                              (read (current-buffer))))
        !           411:                                 (if (> tem 0) tem (- tem)))))
        !           412:                   (throw 'losing 'y)))
        !           413:             (forward-line 1))
        !           414:           (or (looking-at "End tag table\n")
        !           415:               (throw 'losing 'z))
        !           416:           nil))))
        !           417: 
        !           418: (defvar Info-last-search nil
        !           419:   "Default regexp for Info S command to search for.")
        !           420: 
        !           421: (defun Info-search (regexp)
        !           422:   "Search for REGEXP, starting from point, and select node it's found in."
        !           423:   (interactive "sSearch (regexp): ")
        !           424:   (if (equal regexp "")
        !           425:       (setq regexp Info-last-search)
        !           426:     (setq Info-last-search regexp))
        !           427:   (let (found)
        !           428:     (save-excursion
        !           429:      (save-restriction
        !           430:       (widen)
        !           431:       (re-search-forward regexp)
        !           432:       (setq found (point))))
        !           433:     (if found
        !           434:        (progn
        !           435:         (widen)
        !           436:         (goto-char found)
        !           437:         (Info-select-node)))))
        !           438: 
        !           439: (defun Info-extract-pointer (name &optional errorname)
        !           440:   (save-excursion
        !           441:    (goto-char (point-min))
        !           442:    (forward-line 1)
        !           443:    (if (re-search-backward (concat name ":") nil t)
        !           444:        nil
        !           445:      (error (concat "Node has no " (capitalize (or errorname name)))))
        !           446:    (goto-char (match-end 0))
        !           447:    (Info-following-node-name)))
        !           448: 
        !           449: (defun Info-following-node-name (&optional allowedchars)
        !           450:   (skip-chars-forward " \t")
        !           451:   (buffer-substring
        !           452:    (point)
        !           453:    (progn
        !           454:     (skip-chars-forward (or allowedchars "^,\t\n"))
        !           455:     (skip-chars-backward " ")
        !           456:     (point))))
        !           457: 
        !           458: (defun Info-next ()
        !           459:   "Go to the next node of this node."
        !           460:   (interactive)
        !           461:   (Info-goto-node (Info-extract-pointer "next")))
        !           462: 
        !           463: (defun Info-prev ()
        !           464:   "Go to the previous node of this node."
        !           465:   (interactive)
        !           466:   (Info-goto-node (Info-extract-pointer "prev[ious]*" "previous")))
        !           467: 
        !           468: (defun Info-up ()
        !           469:   "Go to the superior node of this node."
        !           470:   (interactive)
        !           471:   (Info-goto-node (Info-extract-pointer "up")))
        !           472: 
        !           473: (defun Info-last ()
        !           474:   "Go back to the last node visited."
        !           475:   (interactive)
        !           476:   (or Info-history
        !           477:       (error "This is the first Info node you looked at"))
        !           478:   (let (filename nodename opoint)
        !           479:     (setq filename (car (car Info-history)))
        !           480:     (setq nodename (car (cdr (car Info-history))))
        !           481:     (setq opoint (car (cdr (cdr (car Info-history)))))
        !           482:     (setq Info-history (cdr Info-history))
        !           483:     (Info-find-node filename nodename)
        !           484:     (setq Info-history (cdr Info-history))
        !           485:     (goto-char opoint)))
        !           486: 
        !           487: (defun Info-directory ()
        !           488:   "Go to the Info directory node."
        !           489:   (interactive)
        !           490:   (Info-find-node "dir" "top"))
        !           491: 
        !           492: (defun Info-follow-reference (footnotename)
        !           493:   "Follow cross reference named NAME to the node it refers to.
        !           494: NAME may be an abbreviation of the reference name."
        !           495:   (interactive
        !           496:    (let ((completion-ignore-case t)
        !           497:         completions str i)
        !           498:      (save-excursion
        !           499:        (goto-char (point-min))
        !           500:        (while (re-search-forward "\\*note[ \n]*[^:\t]*:" nil t)
        !           501:         (setq str (buffer-substring
        !           502:                    (+ (match-beginning 0) 6)
        !           503:                    (1- (point))))
        !           504:         (setq i 0)
        !           505:         (while (setq i (string-match "\n" str i))
        !           506:           (aset str i ?\ ))
        !           507:         (setq completions
        !           508:               (cons (cons str nil)
        !           509:                     completions))))
        !           510:      (if completions
        !           511:         (list (completing-read "Follow reference named: " completions nil t))
        !           512:        (error "No cross-references in this node"))))
        !           513:   (let (target beg i (str (concat "\\*note " footnotename)))
        !           514:     (while (setq i (string-match " " str i))
        !           515:       (setq str (concat (substring str 0 i) "[ \n]*" (substring str (1+ i))))
        !           516:       (setq i (+ i 5)))
        !           517:     (save-excursion
        !           518:       (goto-char (point-min))
        !           519:       (or (re-search-forward str nil t)
        !           520:          (error "No cross-reference named %s" footnotename))
        !           521:       (goto-char (+ (match-beginning 0) 5))
        !           522:       (setq target (Info-extract-menu-node-name "Bad format cross reference")))
        !           523:     (Info-goto-node target)))
        !           524: 
        !           525: (defun Info-extract-menu-node-name (&optional errmessage)
        !           526:   (skip-chars-forward " \t\n")
        !           527:   (let ((beg (point))
        !           528:        str i)
        !           529:     (skip-chars-forward "^:")
        !           530:     (forward-char 1)
        !           531:     (setq str
        !           532:          (if (looking-at ":")
        !           533:              (buffer-substring beg (1- (point)))
        !           534:            (Info-following-node-name "^.,\t\n")))
        !           535:     (while (setq i (string-match "\n" str i))
        !           536:       (aset str i ?\ ))
        !           537:     str))
        !           538: 
        !           539: (defun Info-menu-item-sequence (list)
        !           540:   (while list
        !           541:     (Info-menu-item (car list))
        !           542:     (setq list (cdr list))))
        !           543: 
        !           544: (defun Info-menu (menu-item)
        !           545:   "Go to node for menu item named (or abbreviated) NAME."
        !           546:   (interactive
        !           547:    (let (completions
        !           548:         (completion-ignore-case t))
        !           549:      (save-excursion
        !           550:        (goto-char (point-min))
        !           551:        (if (not (search-forward "\n* menu:" nil t))
        !           552:           (error "No menu in this node"))
        !           553:        (while (re-search-forward
        !           554:                "\n\\* \\([^:\t\n]*\\):" nil t)
        !           555:         (setq completions
        !           556:               (cons (cons (buffer-substring
        !           557:                             (match-beginning 1)
        !           558:                             (match-end 1))
        !           559:                           (match-beginning 1))
        !           560:                     completions))))
        !           561:      (list (completing-read "Menu item: " completions nil t))))
        !           562:   (Info-goto-node (Info-extract-menu-item menu-item)))
        !           563:   
        !           564: (defun Info-extract-menu-item (menu-item)
        !           565:   (save-excursion
        !           566:     (goto-char (point-min))
        !           567:     (or (search-forward "\n* menu:" nil t)
        !           568:        (error "No menu in this node"))
        !           569:     (or (search-forward (concat "\n* " menu-item) nil t)
        !           570:        (error "No such item in menu"))
        !           571:     (beginning-of-line)
        !           572:     (forward-char 2)
        !           573:     (Info-extract-menu-node-name)))
        !           574: 
        !           575: (defun Info-extract-menu-counting (count)
        !           576:   (save-excursion
        !           577:     (goto-char (point-min))
        !           578:     (or (search-forward "\n* menu:" nil t)
        !           579:        (error "No menu in this node"))
        !           580:     (or (search-forward "\n* " nil t count)
        !           581:        (error "Too few items in menu"))
        !           582:     (Info-extract-menu-node-name)))
        !           583: 
        !           584: (defun Info-first-menu-item ()
        !           585:   "Go to the node of the first menu item."
        !           586:   (interactive)
        !           587:   (Info-goto-node (Info-extract-menu-counting 1)))
        !           588: 
        !           589: (defun Info-second-menu-item ()
        !           590:   "Go to the node of the second menu item."
        !           591:   (interactive)
        !           592:   (Info-goto-node (Info-extract-menu-counting 2)))
        !           593: 
        !           594: (defun Info-third-menu-item ()
        !           595:   "Go to the node of the third menu item."
        !           596:   (interactive)
        !           597:   (Info-goto-node (Info-extract-menu-counting 3)))
        !           598: 
        !           599: (defun Info-fourth-menu-item ()
        !           600:   "Go to the node of the fourth menu item."
        !           601:   (interactive)
        !           602:   (Info-goto-node (Info-extract-menu-counting 4)))
        !           603: 
        !           604: (defun Info-fifth-menu-item ()
        !           605:   "Go to the node of the fifth menu item."
        !           606:   (interactive)
        !           607:   (Info-goto-node (Info-extract-menu-counting 5)))
        !           608: 
        !           609: (defun Info-exit ()
        !           610:   "Exit Info by selecting some other buffer."
        !           611:   (interactive)
        !           612:   (switch-to-buffer (prog1 (other-buffer (current-buffer))
        !           613:                           (bury-buffer (current-buffer)))))
        !           614: 
        !           615: (defun Info-undefined ()
        !           616:   "Make command be undefined in Info."
        !           617:   (interactive)
        !           618:   (ding))
        !           619: 
        !           620: (defun Info-help ()
        !           621:   "Enter the Info tutorial."
        !           622:   (interactive)
        !           623:   (Info-find-node "info"
        !           624:                  (if (< (window-height) 23)
        !           625:                      "Help-Small-Screen"
        !           626:                    "Help")))
        !           627: 
        !           628: (defun Info-summary ()
        !           629:   "Display a brief summary of all Info commands."
        !           630:   (interactive)
        !           631:   (save-window-excursion
        !           632:     (switch-to-buffer "*Help*")
        !           633:     (erase-buffer)
        !           634:     (insert (documentation 'Info-mode))
        !           635:     (goto-char (point-min))
        !           636:     (let (ch flag)
        !           637:       (while (progn (setq flag (not (pos-visible-in-window-p (point-max))))
        !           638:                    (message (if flag "Type Space to see more"
        !           639:                               "Type Space to return to Info"))
        !           640:                    (if (/= ?\  (setq ch (read-char)))
        !           641:                        (progn (setq unread-command-char ch) nil)
        !           642:                      flag))
        !           643:        (scroll-up)))))
        !           644: 
        !           645: (defvar Info-mode-map nil
        !           646:   "Keymap containing Info commands.")
        !           647: (if Info-mode-map
        !           648:     nil
        !           649:   (setq Info-mode-map (make-keymap))
        !           650:   (suppress-keymap Info-mode-map)
        !           651:   (define-key Info-mode-map "." 'beginning-of-buffer)
        !           652:   (define-key Info-mode-map " " 'scroll-up)
        !           653:   (define-key Info-mode-map "1" 'Info-first-menu-item)
        !           654:   (define-key Info-mode-map "2" 'Info-second-menu-item)
        !           655:   (define-key Info-mode-map "3" 'Info-third-menu-item)
        !           656:   (define-key Info-mode-map "4" 'Info-fourth-menu-item)
        !           657:   (define-key Info-mode-map "5" 'Info-fifth-menu-item)
        !           658:   (define-key Info-mode-map "6" 'undefined)
        !           659:   (define-key Info-mode-map "7" 'undefined)
        !           660:   (define-key Info-mode-map "8" 'undefined)
        !           661:   (define-key Info-mode-map "9" 'undefined)
        !           662:   (define-key Info-mode-map "0" 'undefined)
        !           663:   (define-key Info-mode-map "?" 'Info-summary)
        !           664:   (define-key Info-mode-map "b" 'beginning-of-buffer)
        !           665:   (define-key Info-mode-map "d" 'Info-directory)
        !           666:   (define-key Info-mode-map "e" 'Info-edit)
        !           667:   (define-key Info-mode-map "f" 'Info-follow-reference)
        !           668:   (define-key Info-mode-map "g" 'Info-goto-node)
        !           669:   (define-key Info-mode-map "h" 'Info-help)
        !           670:   (define-key Info-mode-map "l" 'Info-last)
        !           671:   (define-key Info-mode-map "m" 'Info-menu)
        !           672:   (define-key Info-mode-map "n" 'Info-next)
        !           673:   (define-key Info-mode-map "p" 'Info-prev)
        !           674:   (define-key Info-mode-map "q" 'Info-exit)
        !           675:   (define-key Info-mode-map "s" 'Info-search)
        !           676:   (define-key Info-mode-map "u" 'Info-up)
        !           677:   (define-key Info-mode-map "\177" 'scroll-down))
        !           678: 
        !           679: (defun Info-mode ()
        !           680:   "Info mode provides commands for browsing through the Info documentation tree.
        !           681: Documentation in Info is divided into \"nodes\", each of which
        !           682: discusses one topic and contains references to other nodes
        !           683: which discuss related topics.  Info has commands to follow
        !           684: the references and show you other nodes.
        !           685: 
        !           686: h      Invoke the Info tutorial.
        !           687: 
        !           688: Selecting other nodes:
        !           689: n      Move to the \"next\" node of this node.
        !           690: p      Move to the \"previous\" node of this node.
        !           691: u      Move \"up\" from this node.
        !           692: m      Pick menu item specified by name (or abbreviation).
        !           693:        Picking a menu item causes another node to be selected.
        !           694: f      Follow a cross reference.  Reads name of reference.
        !           695: l      Move to the last node you were at.
        !           696: 
        !           697: Moving within a node:
        !           698: Space  scroll forward a page.     DEL  scroll backward.
        !           699: b      Go to beginning of node.
        !           700: 
        !           701: Advanced commands:
        !           702: q      Quit Info: reselect previously selected buffer.
        !           703: e      Edit contents of selected node.
        !           704: 1      Pick first item in node's menu.
        !           705: 2, 3, 4, 5   Pick second ... fifth item in node's menu.
        !           706: g      Move to node specified by name.
        !           707:        You may include a filename as well, as (FILENAME)NODENAME.
        !           708: s      Search through this Info file for specified regexp,
        !           709:        and select the node in which the next occurrence is found."
        !           710:   (kill-all-local-variables)
        !           711:   (setq major-mode 'Info-mode)
        !           712:   (setq mode-name "Info")
        !           713:   (use-local-map Info-mode-map)
        !           714:   (set-syntax-table text-mode-syntax-table)
        !           715:   (setq local-abbrev-table text-mode-abbrev-table)
        !           716:   (setq case-fold-search t)
        !           717:   (setq buffer-read-only t)
        !           718:   (Info-set-mode-line))
        !           719: 
        !           720: (defvar Info-edit-map nil
        !           721:   "Local keymap used within `e' command of Info.")
        !           722: (if Info-edit-map
        !           723:     nil
        !           724:   (setq Info-edit-map (copy-alist text-mode-map))
        !           725:   (define-key Info-edit-map "\C-c\C-c" 'Info-cease-edit))
        !           726: 
        !           727: (defun Info-edit-mode ()
        !           728:   "Major mode for editing the contents of an Info node.
        !           729: Like text mode with the addition of Info-cease-edit
        !           730: which returns to Info mode for browsing.
        !           731: \\{Info-edit-map}"
        !           732:   )
        !           733: 
        !           734: (defun Info-edit ()
        !           735:   "Edit the contents of this Info node.
        !           736: Allowed only if variable Info-enable-edit is non-nil."
        !           737:   (interactive)
        !           738:   (or Info-enable-edit
        !           739:       (error "Editing info nodes is not enabled"))
        !           740:   (use-local-map Info-edit-map)
        !           741:   (setq major-mode 'Info-edit-mode)
        !           742:   (setq mode-name "Info Edit")
        !           743:   (setq mode-line-format default-mode-line-format)
        !           744:   (setq buffer-read-only nil)
        !           745:   ;; Make mode line update.
        !           746:   (set-buffer-modified-p (buffer-modified-p))
        !           747:   (message (substitute-command-keys
        !           748:             "Editing: Type \\[Info-cease-edit] to return to info")))
        !           749: 
        !           750: (defun Info-cease-edit ()
        !           751:   "Finish editing Info node; switch back to Info proper."
        !           752:   (interactive)
        !           753:   ;; Do this first, so nothing has changed if user C-g's at query.
        !           754:   (and (buffer-modified-p)
        !           755:        (y-or-n-p "Save the file? ")
        !           756:        (save-buffer))
        !           757:   (use-local-map Info-mode-map)
        !           758:   (setq major-mode 'Info-mode)
        !           759:   (setq mode-name "Info")
        !           760:   (Info-set-mode-line)
        !           761:   (setq buffer-read-only t)
        !           762:   ;; Make mode line update.
        !           763:   (set-buffer-modified-p (buffer-modified-p))
        !           764:   (and (marker-position Info-tag-table-marker)
        !           765:        (buffer-modified-p)
        !           766:        (message "Tags may have changed.  Use Info-tagify if necessary")))

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.