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