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