Annotation of GNUtools/emacs/lisp/info.el, revision 1.1.1.1

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