|
|
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")))
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.