comparison lisp/info.el @ 442:abe6d1db359e r21-2-36

Import from CVS: tag r21-2-36
author cvs
date Mon, 13 Aug 2007 11:35:02 +0200
parents 8de8e3f6228a
children 576fb035e263
comparison
equal deleted inserted replaced
441:72a7cfa4a488 442:abe6d1db359e
20 ;; WITHOUT ANY WARRANTY; without even the implied warranty of 20 ;; WITHOUT ANY WARRANTY; without even the implied warranty of
21 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 21 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
22 ;; General Public License for more details. 22 ;; General Public License for more details.
23 23
24 ;; You should have received a copy of the GNU General Public License 24 ;; You should have received a copy of the GNU General Public License
25 ;; along with XEmacs; see the file COPYING. If not, write to the 25 ;; along with XEmacs; see the file COPYING. If not, write to the
26 ;; Free Software Foundation, Inc., 59 Temple Place - Suite 330, 26 ;; Free Software Foundation, Inc., 59 Temple Place - Suite 330,
27 ;; Boston, MA 02111-1307, USA. 27 ;; Boston, MA 02111-1307, USA.
28 28
29 ;;; Synched up with: Not synched with FSF. 29 ;;; Synched up with: Not synched with FSF.
30 30
306 ;; 306 ;;
307 ;; Added automatic dir/localdir (re)building capability for directories that 307 ;; Added automatic dir/localdir (re)building capability for directories that
308 ;; contain none or when it has become older than info files in the same 308 ;; contain none or when it has become older than info files in the same
309 ;; directory. 309 ;; directory.
310 310
311 ;; Modified 1998-09-23 by Didier Verna <verna@inf.enst.fr> 311 ;; Modified 1998-09-23 by Didier Verna <didier@xemacs.org>
312 ;; 312 ;;
313 ;; Use the new macro `with-search-caps-disable-folding' 313 ;; Use the new macro `with-search-caps-disable-folding'
314 314
315 ;; Code: 315 ;; Code:
316 (eval-when-compile 316 (eval-when-compile
400 use any existing `dir' or `localdir' file and ignore info 400 use any existing `dir' or `localdir' file and ignore info
401 directories containing none 401 directories containing none
402 `always' auto-generate a directory listing ignoring existing 402 `always' auto-generate a directory listing ignoring existing
403 `dir' and `localdir' files 403 `dir' and `localdir' files
404 `if-missing', the default, auto-generates a directory listing 404 `if-missing', the default, auto-generates a directory listing
405 if no `dir' or `localdir' file is present. Otherwise the 405 if no `dir' or `localdir' file is present. Otherwise the
406 contents of any of these files is used instead. 406 contents of any of these files is used instead.
407 `if-outdated' auto-generates a directory listing if the `dir' 407 `if-outdated' auto-generates a directory listing if the `dir'
408 and `localdir' are either inexistent or outdated (touched 408 and `localdir' are either inexistent or outdated (touched
409 less recently than an info file in the same directory)." 409 less recently than an info file in the same directory)."
410 :type '(choice (const :tag "never" never) 410 :type '(choice (const :tag "never" never)
411 (const :tag "always" always) 411 (const :tag "always" always)
412 (const :tag "if-missing" if-missing) 412 (const :tag "if-missing" if-missing)
413 (const :tag "if-outdated" if-outdated)) 413 (const :tag "if-outdated" if-outdated))
414 :group 'info) 414 :group 'info)
415 415
416 (defcustom Info-save-auto-generated-dir nil 416 (defcustom Info-save-auto-generated-dir 'never
417 "*Whether an auto-generated info directory listing should be saved. 417 "*Whether an auto-generated info directory listing should be saved.
418 Possible values are: 418 Possible values are:
419 nil or `never', the default, auto-generated info directory 419 nil or `never', the default, auto-generated info directory
420 information will never be saved. 420 information will never be saved.
421 `always', auto-generated info directory information will be saved to 421 `always', auto-generated info directory information will be saved to
422 a `dir' file in the same directory overwriting it if it exists 422 a `dir' file in the same directory overwriting it if it exists
423 `conservative', auto-generated info directory information will be saved 423 `conservative', auto-generated info directory information will be saved
424 to a `dir' file in the same directory but the user is asked before 424 to a `dir' file in the same directory but the user is asked before
425 overwriting any existing file." 425 overwriting any existing file."
426 :type '(choice (const :tag "never" never) 426 :type '(choice (const :tag "never" never)
427 (const :tag "always" always) 427 (const :tag "always" always)
428 (const :tag "conservative" conservative)) 428 (const :tag "conservative" conservative))
429 :group 'info) 429 :group 'info)
461 (defface info-xref '((t (:bold t))) 461 (defface info-xref '((t (:bold t)))
462 "Face used for cross-references in info." 462 "Face used for cross-references in info."
463 :group 'info-faces) 463 :group 'info-faces)
464 464
465 ;; Is this right for NT? .zip, with -c for to stdout, right? 465 ;; Is this right for NT? .zip, with -c for to stdout, right?
466 (defvar Info-suffix-list '( ("" . nil) 466 (defvar Info-suffix-list '( ("" . nil)
467 (".info" . nil) 467 (".info" . nil)
468 (".info.bz2" . "bzip2 -dc %s") 468 (".info.bz2" . "bzip2 -dc %s")
469 (".info.gz" . "gzip -dc %s") 469 (".info.gz" . "gzip -dc %s")
470 (".info-z" . "gzip -dc %s") 470 (".info-z" . "gzip -dc %s")
471 (".info.Z" . "uncompress -c %s") 471 (".info.Z" . "uncompress -c %s")
492 or nil if current info file is not split into subfiles.") 492 or nil if current info file is not split into subfiles.")
493 493
494 (defvar Info-current-node nil 494 (defvar Info-current-node nil
495 "Name of node that Info is now looking at, or nil.") 495 "Name of node that Info is now looking at, or nil.")
496 496
497 (defvar Info-tag-table-marker (make-marker) 497 (defvar Info-tag-table-marker nil
498 "Marker pointing at beginning of current Info file's tag table. 498 "Marker pointing at beginning of current Info file's tag table.
499 Marker points nowhere if file has no tag table.") 499 Marker points nowhere if file has no tag table.")
500
501 (defvar Info-tag-table-buffer nil)
500 502
501 (defvar Info-current-file-completions nil 503 (defvar Info-current-file-completions nil
502 "Cached completion list for current Info file.") 504 "Cached completion list for current Info file.")
503 505
504 (defvar Info-current-annotation-completions nil 506 (defvar Info-current-annotation-completions nil
535 This is the file .../info/dir, which contains the topmost node of the 537 This is the file .../info/dir, which contains the topmost node of the
536 Info hierarchy. The first time you invoke Info you start off 538 Info hierarchy. The first time you invoke Info you start off
537 looking at that node, which is (dir)Top. 539 looking at that node, which is (dir)Top.
538  540 
539 File: dir Node: Top This is the top of the INFO tree 541 File: dir Node: Top This is the top of the INFO tree
540 This (the Directory node) gives a menu of major topics. 542 This (the Directory node) gives a menu of major topics.
541 543
542 * Menu: The list of major topics begins on the next line. 544 * Menu: The list of major topics begins on the next line.
543 545
544 ") 546 ")
545 547
590 (while f 592 (while f
591 (if (and (file-exists-p (car f)) (not (get-file-buffer (car f)))) 593 (if (and (file-exists-p (car f)) (not (get-file-buffer (car f))))
592 (bury-buffer (find-file-noselect (car f)))) 594 (bury-buffer (find-file-noselect (car f))))
593 (setq f (cdr f))))) 595 (setq f (cdr f)))))
594 596
597 ;;;###autoload
595 (defun Info-find-node (filename &optional nodename no-going-back tryfile line) 598 (defun Info-find-node (filename &optional nodename no-going-back tryfile line)
596 "Go to an info node specified as separate FILENAME and NODENAME. 599 "Go to an info node specified as separate FILENAME and NODENAME.
597 Look for a plausible filename, or if not found then look for URL's and 600 Look for a plausible filename, or if not found then look for URL's and
598 dispatch to the appropriate fn. NO-GOING-BACK is non-nil if 601 dispatch to the appropriate fn. NO-GOING-BACK is non-nil if
599 recovering from an error in this function; it says do not attempt 602 recovering from an error in this function; it says do not attempt
605 ;; empty filename is simple case 608 ;; empty filename is simple case
606 ((null filename) 609 ((null filename)
607 (Info-find-file-node nil nodename no-going-back tryfile line)) 610 (Info-find-file-node nil nodename no-going-back tryfile line))
608 ;; Convert filename to lower case if not found as specified. 611 ;; Convert filename to lower case if not found as specified.
609 ;; Expand it, look harder... 612 ;; Expand it, look harder...
610 ((let (temp temp-downcase found 613 ((let (temp temp-downcase found
611 (fname (substitute-in-file-name filename))) 614 (fname (substitute-in-file-name filename)))
612 (let ((dirs (cond 615 (let ((dirs (cond
613 ((string-match "^\\./" fname) ; If specified name starts with `./' 616 ((string-match "^\\./" fname) ; If specified name starts with `./'
614 (list default-directory)) ; then just try current directory. 617 (list default-directory)) ; then just try current directory.
615 ((file-name-absolute-p fname) 618 ((file-name-absolute-p fname)
626 (if (equal temp-downcase temp) (setq temp-downcase nil)) 629 (if (equal temp-downcase temp) (setq temp-downcase nil))
627 ;; Try several variants of specified name. 630 ;; Try several variants of specified name.
628 ;; Try downcasing, appending a suffix, or both. 631 ;; Try downcasing, appending a suffix, or both.
629 (setq found (Info-suffixed-file temp temp-downcase)) 632 (setq found (Info-suffixed-file temp temp-downcase))
630 (setq dirs (cdr dirs))) 633 (setq dirs (cdr dirs)))
631 (if found 634 (if found
632 (progn (setq filename (expand-file-name found)) 635 (progn (setq filename (expand-file-name found))
633 t)))) 636 t))))
634 (Info-find-file-node filename nodename no-going-back tryfile line)) 637 (Info-find-file-node filename nodename no-going-back tryfile line))
635 ;; Look for a URL. This pattern is stolen from w3.el to prevent 638 ;; Look for a URL. This pattern is stolen from w3.el to prevent
636 ;; loading it if we won't need it. 639 ;; loading it if we won't need it.
648 &optional no-going-back tryfile line) 651 &optional no-going-back tryfile line)
649 ;; This is the guts of what was Info-find-node. Whoever wrote this 652 ;; This is the guts of what was Info-find-node. Whoever wrote this
650 ;; should be locked up where they can't do any more harm. 653 ;; should be locked up where they can't do any more harm.
651 654
652 ;; Go into info buffer. 655 ;; Go into info buffer.
653 (switch-to-buffer "*info*") 656 (or (eq major-mode 'Info-mode)
657 (switch-to-buffer "*info*"))
654 (buffer-disable-undo (current-buffer)) 658 (buffer-disable-undo (current-buffer))
655 (run-hooks 'Info-startup-hook) 659 (run-hooks 'Info-startup-hook)
656 (or (eq major-mode 'Info-mode) 660 (or (eq major-mode 'Info-mode)
657 (Info-mode)) 661 (Info-mode))
658 (or (null filename) 662 (or (null filename)
659 (equal Info-current-file filename) 663 (equal Info-current-file filename)
660 (not Info-novice) 664 (not Info-novice)
661 (string= "dir" (file-name-nondirectory Info-current-file)) 665 (string= "dir" (file-name-nondirectory Info-current-file))
662 (if (y-or-n-p-maybe-dialog-box 666 (if (y-or-n-p
663 (format "Leave Info file `%s'? " 667 (format "Leave Info file `%s'? "
664 (file-name-nondirectory Info-current-file))) 668 (file-name-nondirectory Info-current-file)))
665 (message "") 669 (message "")
666 (keyboard-quit))) 670 (keyboard-quit)))
667 ;; Record the node we are leaving. 671 ;; Record the node we are leaving.
701 (if (save-excursion 705 (if (save-excursion
702 (forward-line 2) 706 (forward-line 2)
703 (looking-at "(Indirect)\n")) 707 (looking-at "(Indirect)\n"))
704 ;; It is indirect. Copy it to another buffer 708 ;; It is indirect. Copy it to another buffer
705 ;; and record that the tag table is in that buffer. 709 ;; and record that the tag table is in that buffer.
706 (save-excursion 710 (let ((buf (current-buffer))
707 (let ((buf (current-buffer))) 711 (m Info-tag-table-marker))
708 (set-buffer 712 (or
709 (get-buffer-create " *info tag table*")) 713 Info-tag-table-buffer
710 (buffer-disable-undo (current-buffer)) 714 (setq
711 (setq case-fold-search t) 715 Info-tag-table-buffer
712 (erase-buffer) 716 (generate-new-buffer " *info tag table*")))
713 (insert-buffer-substring buf) 717 (save-excursion
714 (set-marker Info-tag-table-marker 718 (set-buffer Info-tag-table-buffer)
715 (match-end 0)))) 719 (buffer-disable-undo (current-buffer))
720 (setq case-fold-search t)
721 (erase-buffer)
722 (insert-buffer-substring buf)
723 (set-marker m (match-end 0))))
716 (set-marker Info-tag-table-marker pos)))) 724 (set-marker Info-tag-table-marker pos))))
717 (setq Info-current-file 725 (setq Info-current-file
718 (file-name-sans-versions buffer-file-name)))) 726 (file-name-sans-versions buffer-file-name))))
719 (if (equal nodename "*") 727 (if (equal nodename "*")
720 (progn (setq Info-current-node nodename) 728 (progn (setq Info-current-node nodename)
727 (found t)) 735 (found t))
728 ;; First get advice from tag table if file has one. 736 ;; First get advice from tag table if file has one.
729 ;; Also, if this is an indirect info file, 737 ;; Also, if this is an indirect info file,
730 ;; read the proper subfile into this buffer. 738 ;; read the proper subfile into this buffer.
731 (if (marker-position Info-tag-table-marker) 739 (if (marker-position Info-tag-table-marker)
732 (save-excursion 740 (let (foun found-mode (m Info-tag-table-marker))
733 (set-buffer (marker-buffer Info-tag-table-marker)) 741 (save-excursion
734 (goto-char Info-tag-table-marker) 742 (set-buffer (marker-buffer Info-tag-table-marker))
735 (if (re-search-forward regexp nil t) 743 (goto-char m)
736 (progn 744 (setq foun (re-search-forward regexp nil t))
737 (setq guesspos (read (current-buffer))) 745 (if foun
738 ;; If this is an indirect file, 746 (setq guesspos (read (current-buffer))))
739 ;; determine which file really holds this node 747 (setq found-mode major-mode))
740 ;; and read it in. 748 (if foun
741 (if (not (eq (current-buffer) (get-buffer "*info*"))) 749 ;; If this is an indirect file,
742 (setq guesspos 750 ;; determine which file really holds this node
743 (Info-read-subfile guesspos))))))) 751 ;; and read it in.
752 (if (not (eq major-mode found-mode))
753 (setq guesspos
754 (Info-read-subfile guesspos))))))
744 (goto-char (max (point-min) (- guesspos 1000))) 755 (goto-char (max (point-min) (- guesspos 1000)))
745 ;; Now search from our advised position (or from beg of buffer) 756 ;; Now search from our advised position (or from beg of buffer)
746 ;; to find the actual node. 757 ;; to find the actual node.
747 (catch 'foo 758 (catch 'foo
748 (while (search-forward "\n\^_" nil t) 759 (while (search-forward "\n\^_" nil t)
868 (set-buffer (or buf 879 (set-buffer (or buf
869 (generate-new-buffer 880 (generate-new-buffer
870 (if (string-match "localdir" file) 881 (if (string-match "localdir" file)
871 "localdir" 882 "localdir"
872 "info dir")))) 883 "info dir"))))
873 (if (not buf) 884 (if (not buf)
874 (insert-file-contents file)) 885 (insert-file-contents file))
875 (if (string-match "localdir" (buffer-name)) 886 (if (string-match "localdir" (buffer-name))
876 (setq lbuffers (cons (current-buffer) lbuffers)) 887 (setq lbuffers (cons (current-buffer) lbuffers))
877 (setq buffers (cons (current-buffer) buffers))) 888 (setq buffers (cons (current-buffer) buffers)))
878 (if attrs 889 (if attrs
879 (setq Info-dir-file-attributes 890 (setq Info-dir-file-attributes
880 (cons (cons file attrs) 891 (cons (cons file attrs)
881 Info-dir-file-attributes))))))) 892 Info-dir-file-attributes)))))))
882 (or (cdr dirs) (setq Info-dir-contents-directory (car dirs))) 893 (or (cdr dirs) (setq Info-dir-contents-directory (car dirs)))
883 (setq dirs (cdr dirs)))) 894 (setq dirs (cdr dirs))))
884 895
885 ;; ensure that the localdir files are inserted last, and reverse 896 ;; ensure that the localdir files are inserted last, and reverse
886 ;; the list of them so that when they get pushed in, they appear 897 ;; the list of them so that when they get pushed in, they appear
887 ;; in the same order they got specified in the path, from top to 898 ;; in the same order they got specified in the path, from top to
888 ;; bottom. 899 ;; bottom.
889 (nconc buffers (reverse lbuffers)) 900 (nconc buffers (reverse lbuffers))
890 901
891 (or buffers 902 (or buffers
892 (error "Can't find the Info directory node")) 903 (error "Can't find the Info directory node"))
893 ;; Distinguish the dir file that comes with Emacs from all the 904 ;; Distinguish the dir file that comes with Emacs from all the
894 ;; others. Yes, that is really what this is supposed to do. 905 ;; others. Yes, that is really what this is supposed to do.
895 ;; If it doesn't work, fix it. 906 ;; If it doesn't work, fix it.
954 (search-forward "\n\^_" nil 'move) 965 (search-forward "\n\^_" nil 'move)
955 (beginning-of-line) 966 (beginning-of-line)
956 (setq end (point)) 967 (setq end (point))
957 (setq nodes (cons (list nodename other beg end) nodes)))))) 968 (setq nodes (cons (list nodename other beg end) nodes))))))
958 (setq others (cdr others)))) 969 (setq others (cdr others))))
959 970
960 ;; Add to the main menu a menu item for each other node. 971 ;; Add to the main menu a menu item for each other node.
961 (re-search-forward "^\\* Menu:" nil t) 972 (re-search-forward "^\\* Menu:" nil t)
962 (forward-line 1) 973 (forward-line 1)
963 (let ((menu-items '("top")) 974 (let ((menu-items '("top"))
964 (nodes nodes) 975 (nodes nodes)
1014 (unless (or (not (file-exists-p (file-name-directory file))) 1025 (unless (or (not (file-exists-p (file-name-directory file)))
1015 (null (directory-files (file-name-directory file) nil "\\.info"))) 1026 (null (directory-files (file-name-directory file) nil "\\.info")))
1016 (if (not (find-buffer-visiting file)) 1027 (if (not (find-buffer-visiting file))
1017 (if (not (file-exists-p file)) 1028 (if (not (file-exists-p file))
1018 (if (or (eq Info-auto-generate-directory 'always) 1029 (if (or (eq Info-auto-generate-directory 'always)
1019 (eq Info-auto-generate-directory 'if-missing)) 1030 (eq Info-auto-generate-directory 'if-missing))
1020 (Info-build-dir-anew (file-name-directory file))) 1031 (Info-build-dir-anew (file-name-directory file)))
1021 (if (or (eq Info-auto-generate-directory 'always) 1032 (if (or (eq Info-auto-generate-directory 'always)
1022 (and (eq Info-auto-generate-directory 'if-outdated) 1033 (and (eq Info-auto-generate-directory 'if-outdated)
1023 (Info-dir-outdated-p file))) 1034 (Info-dir-outdated-p file)))
1024 (Info-rebuild-dir file)))))) 1035 (Info-rebuild-dir file))))))
1032 directory has been modified more recently." 1043 directory has been modified more recently."
1033 (let ((dir-mod-time (nth 5 (file-attributes file))) 1044 (let ((dir-mod-time (nth 5 (file-attributes file)))
1034 f-mod-time 1045 f-mod-time
1035 newer) 1046 newer)
1036 (setq Info-dir-newer-info-files nil) 1047 (setq Info-dir-newer-info-files nil)
1037 (mapcar 1048 (mapcar
1038 #'(lambda (f) 1049 #'(lambda (f)
1039 (prog2 1050 (prog2
1040 (setq f-mod-time (nth 5 (file-attributes f))) 1051 (setq f-mod-time (nth 5 (file-attributes f)))
1041 (setq newer (or (> (car f-mod-time) (car dir-mod-time)) 1052 (setq newer (or (> (car f-mod-time) (car dir-mod-time))
1042 (and (= (car f-mod-time) (car dir-mod-time)) 1053 (and (= (car f-mod-time) (car dir-mod-time))
1043 (> (car (cdr f-mod-time)) (car (cdr dir-mod-time)))))) 1054 (> (car (cdr f-mod-time)) (car (cdr dir-mod-time))))))
1044 (if (and (file-readable-p f) 1055 (if (and (file-readable-p f)
1045 newer) 1056 newer)
1046 (setq Info-dir-newer-info-files 1057 (setq Info-dir-newer-info-files
1047 (cons f Info-dir-newer-info-files))))) 1058 (cons f Info-dir-newer-info-files)))))
1048 (directory-files (file-name-directory file) 1059 (directory-files (file-name-directory file)
1049 'fullname 1060 'fullname
1050 ".*\\.info\\(\\.gz\\|\\.bz2\\|\\.Z\\|-z\\|\\.zip\\)?$" 1061 ".*\\.info\\(\\.gz\\|\\.bz2\\|\\.Z\\|-z\\|\\.zip\\)?$"
1051 'nosort 1062 'nosort
1080 (while (re-search-forward "^\\* \\([^:]+\\):\\([ \t]*(\\([^)]*\\))\\w*\\.\\|:\\)" nil t) 1091 (while (re-search-forward "^\\* \\([^:]+\\):\\([ \t]*(\\([^)]*\\))\\w*\\.\\|:\\)" nil t)
1081 (setq entry (list (match-string 2) 1092 (setq entry (list (match-string 2)
1082 (match-string 1) 1093 (match-string 1)
1083 (downcase (or (match-string 3) 1094 (downcase (or (match-string 3)
1084 (match-string 1))))) 1095 (match-string 1)))))
1085 (setq entry 1096 (setq entry
1086 (cons (nreverse 1097 (cons (nreverse
1087 (cdr 1098 (cdr
1088 (nreverse 1099 (nreverse
1089 (split-string 1100 (split-string
1090 (buffer-substring 1101 (buffer-substring
1091 (re-search-forward "[ \t]*" nil t) 1102 (re-search-forward "[ \t]*" nil t)
1092 (or (and (re-search-forward "^[^ \t]" nil t) 1103 (or (and (re-search-forward "^[^ \t]" nil t)
1093 (goto-char (match-beginning 0))) 1104 (goto-char (match-beginning 0)))
1094 (point-max))) 1105 (point-max)))
1095 "[ \t]*\n[ \t]*")))) 1106 "[ \t]*\n[ \t]*"))))
1106 (setq len (length (concat (car e) 1117 (setq len (length (concat (car e)
1107 (car (cdr e))))) 1118 (car (cdr e)))))
1108 (if (> len description-col) 1119 (if (> len description-col)
1109 (setq description-col len))) 1120 (setq description-col len)))
1110 entries) 1121 entries)
1111 (setq description-col (+ 5 description-col)) 1122 (setq description-col (+ 5 description-col))
1112 (mapcar #'(lambda (e) 1123 (mapcar #'(lambda (e)
1113 (setq e (cdr e)) ; Drop filename 1124 (setq e (cdr e)) ; Drop filename
1114 (insert "* " (car e) ":" (car (cdr e))) 1125 (insert "* " (car e) ":" (car (cdr e)))
1115 (setq e (car (cdr (cdr e)))) 1126 (setq e (car (cdr (cdr e))))
1116 (while e 1127 (while e
1121 (insert "\n"))) 1132 (insert "\n")))
1122 1133
1123 1134
1124 (defun Info-build-dir-anew (directory) 1135 (defun Info-build-dir-anew (directory)
1125 "Build info directory information for DIRECTORY. 1136 "Build info directory information for DIRECTORY.
1126 The generated directory listing may be saved to a `dir' according 1137 The generated directory listing may be saved to a `dir' according
1127 to the value of `Info-save-auto-generated-dir'" 1138 to the value of `Info-save-auto-generated-dir'"
1128 (save-excursion 1139 (save-excursion
1129 (let* ((dirfile (expand-file-name "dir" directory)) 1140 (let* ((dirfile (expand-file-name "dir" directory))
1130 (to-temp (or (null Info-save-auto-generated-dir) 1141 (to-temp (or (null Info-save-auto-generated-dir)
1131 (eq Info-save-auto-generated-dir 'never) 1142 (eq Info-save-auto-generated-dir 'never)
1132 (and (not (file-writable-p dirfile)) 1143 (and (not (file-writable-p dirfile))
1133 (message "File not writable %s. Using temporary." dirfile)))) 1144 (message "File not writable %s. Using temporary." dirfile))))
1134 (info-files 1145 (info-files
1135 (directory-files directory 1146 (directory-files directory
1136 'fullname 1147 'fullname
1137 ".*\\.info\\(.gz\\|.Z\\|-z\\|.zip\\)?$" 1148 ".*\\.info\\(.gz\\|.Z\\|-z\\|.zip\\)?$"
1138 nil 1149 nil
1139 t))) 1150 t)))
1143 (set-buffer (find-file-noselect dirfile t)) 1154 (set-buffer (find-file-noselect dirfile t))
1144 (setq buffer-read-only nil) 1155 (setq buffer-read-only nil)
1145 (erase-buffer) 1156 (erase-buffer)
1146 (insert Info-dir-prologue 1157 (insert Info-dir-prologue
1147 "Info files in " directory ":\n\n") 1158 "Info files in " directory ":\n\n")
1148 (Info-dump-dir-entries 1159 (Info-dump-dir-entries
1149 (mapcar 1160 (mapcar
1150 #'(lambda (f) 1161 #'(lambda (f)
1151 (or (Info-extract-dir-entry-from f) 1162 (or (Info-extract-dir-entry-from f)
1152 (list 'dummy 1163 (list 'dummy
1153 (progn 1164 (progn
1154 (string-match "\\(.*\\)\\.info\\(.gz\\|.Z\\|-z\\|.zip\\)?$" 1165 (string-match "\\(.*\\)\\.info\\(.gz\\|.Z\\|-z\\|.zip\\)?$"
1155 (file-name-nondirectory f)) 1166 (file-name-nondirectory f))
1156 (capitalize (match-string 1 (file-name-nondirectory f)))) 1167 (capitalize (match-string 1 (file-name-nondirectory f))))
1157 ":" 1168 ":"
1158 (list Info-no-description-string)))) 1169 (list Info-no-description-string))))
1159 info-files)) 1170 info-files))
1165 (message "Creating %s...done" dirfile))))) 1176 (message "Creating %s...done" dirfile)))))
1166 1177
1167 1178
1168 (defun Info-rebuild-dir (file) 1179 (defun Info-rebuild-dir (file)
1169 "Build info directory information in the directory of dir FILE. 1180 "Build info directory information in the directory of dir FILE.
1170 Description of info files are merged from the info files in the 1181 Description of info files are merged from the info files in the
1171 directory and the contents of FILE with the description in info files 1182 directory and the contents of FILE with the description in info files
1172 taking precedence over descriptions in FILE. 1183 taking precedence over descriptions in FILE.
1173 The generated directory listing may be saved to a `dir' according to 1184 The generated directory listing may be saved to a `dir' according to
1174 the value of `Info-save-auto-generated-dir' " 1185 the value of `Info-save-auto-generated-dir' "
1175 (save-excursion 1186 (save-excursion
1176 (save-restriction 1187 (save-restriction
1177 (let (dir-section-contents dir-full-contents 1188 (let (dir-section-contents dir-full-contents
1178 dir-entry 1189 dir-entry
1179 file-dir-entry 1190 file-dir-entry
1180 mark next-section 1191 mark next-section
1181 not-first-section 1192 not-first-section
1182 (to-temp 1193 (to-temp
1183 (or (null Info-save-auto-generated-dir) 1194 (or (null Info-save-auto-generated-dir)
1184 (eq Info-save-auto-generated-dir 'never) 1195 (eq Info-save-auto-generated-dir 'never)
1185 (and (eq Info-save-auto-generated-dir 'always) 1196 (and (eq Info-save-auto-generated-dir 'always)
1186 (not (file-writable-p file)) 1197 (not (file-writable-p file))
1187 (message "File not writable %s. Using temporary." file)) 1198 (message "File not writable %s. Using temporary." file))
1188 (and (eq Info-save-auto-generated-dir 'conservative) 1199 (and (eq Info-save-auto-generated-dir 'conservative)
1189 (or (and (not (file-writable-p file)) 1200 (or (and (not (file-writable-p file))
1190 (message "File not writable %s. Using temporary." file)) 1201 (message "File not writable %s. Using temporary." file))
1191 (not (y-or-n-p 1202 (not (y-or-n-p
1192 (message "%s is outdated. Overwrite ? " 1203 (message "%s is outdated. Overwrite ? "
1193 file)))))))) 1204 file))))))))
1194 (set-buffer (find-file-noselect file t)) 1205 (set-buffer (find-file-noselect file t))
1195 (setq buffer-read-only nil) 1206 (setq buffer-read-only nil)
1196 (if to-temp 1207 (if to-temp
1197 (message "Rebuilding temporary %s..." file) 1208 (message "Rebuilding temporary %s..." file)
1230 (file-name-nondirectory file))) 1241 (file-name-nondirectory file)))
1231 dir-full-contents)) 1242 dir-full-contents))
1232 (if file-dir-entry 1243 (if file-dir-entry
1233 (setq dir-section-contents (cons file-dir-entry 1244 (setq dir-section-contents (cons file-dir-entry
1234 dir-section-contents)) 1245 dir-section-contents))
1235 (setq dir-section-contents 1246 (setq dir-section-contents
1236 (cons (list 'dummy 1247 (cons (list 'dummy
1237 (capitalize (file-name-sans-extension 1248 (capitalize (file-name-sans-extension
1238 (file-name-nondirectory file))) 1249 (file-name-nondirectory file)))
1239 ":" 1250 ":"
1240 (list Info-no-description-string)) 1251 (list Info-no-description-string))
1241 dir-section-contents)))))) 1252 dir-section-contents))))))
1242 Info-dir-newer-info-files) 1253 Info-dir-newer-info-files)
1243 (delete-region (point-min) (point-max)) 1254 (delete-region (point-min) (point-max))
1244 (Info-dump-dir-entries (nreverse dir-section-contents)) 1255 (Info-dump-dir-entries (nreverse dir-section-contents))
1245 (widen) 1256 (widen)
1257 (set-buffer-modified-p nil) 1268 (set-buffer-modified-p nil)
1258 (message "Rebuilding temporary %s...done" file)) 1269 (message "Rebuilding temporary %s...done" file))
1259 (save-buffer) 1270 (save-buffer)
1260 (message "Rebuilding %s...done" file)))))) 1271 (message "Rebuilding %s...done" file))))))
1261 1272
1262 ;;;###autoload 1273 ;;;###autoload
1263 (defun Info-batch-rebuild-dir () 1274 (defun Info-batch-rebuild-dir ()
1264 "(Re)build info `dir' files in the directories remaining on the command line. 1275 "(Re)build info `dir' files in the directories remaining on the command line.
1265 Use this from the command line, with `-batch'; 1276 Use this from the command line, with `-batch';
1266 it won't work in an interactive Emacs. 1277 it won't work in an interactive Emacs.
1267 Each file is processed even if an error occurred previously. 1278 Each file is processed even if an error occurred previously.
1277 (if (not (file-directory-p (car command-line-args-left))) 1288 (if (not (file-directory-p (car command-line-args-left)))
1278 (message "Warning: Skipped %s. Not a directory." 1289 (message "Warning: Skipped %s. Not a directory."
1279 (car command-line-args-left)) 1290 (car command-line-args-left))
1280 (setq dir (expand-file-name "dir" (car command-line-args-left))) 1291 (setq dir (expand-file-name "dir" (car command-line-args-left)))
1281 (setq localdir (expand-file-name "localdir" (car command-line-args-left))) 1292 (setq localdir (expand-file-name "localdir" (car command-line-args-left)))
1282 (cond 1293 (cond
1283 ((file-exists-p dir) 1294 ((file-exists-p dir)
1284 (Info-rebuild-dir dir)) 1295 (Info-rebuild-dir dir))
1285 ((file-exists-p localdir) 1296 ((file-exists-p localdir)
1286 (Info-rebuild-dir localdir)) 1297 (Info-rebuild-dir localdir))
1287 (t 1298 (t
1308 (while (and p (not (equal (car p) dir))) 1319 (while (and p (not (equal (car p) dir)))
1309 (setq p (cdr p))) 1320 (setq p (cdr p)))
1310 (if p (file-name-nondirectory file) file))) 1321 (if p (file-name-nondirectory file) file)))
1311 1322
1312 (defun Info-read-subfile (nodepos) 1323 (defun Info-read-subfile (nodepos)
1313 (set-buffer (marker-buffer Info-tag-table-marker))
1314 (goto-char (point-min))
1315 (search-forward "\n\^_")
1316 (let (lastfilepos 1324 (let (lastfilepos
1317 lastfilename) 1325 lastfilename)
1318 (forward-line 2) 1326 (save-excursion
1319 (catch 'foo 1327 (set-buffer (marker-buffer Info-tag-table-marker))
1320 (while (not (looking-at "\^_")) 1328 (goto-char (point-min))
1321 (if (not (eolp)) 1329 (search-forward "\n\^_")
1322 (let ((beg (point)) 1330 (forward-line 2)
1323 thisfilepos thisfilename) 1331 (catch 'foo
1324 (search-forward ": ") 1332 (while (not (looking-at "\^_"))
1325 (setq thisfilename (buffer-substring beg (- (point) 2))) 1333 (if (not (eolp))
1326 (setq thisfilepos (read (current-buffer))) 1334 (let ((beg (point))
1327 ;; read in version 19 stops at the end of number. 1335 thisfilepos thisfilename)
1328 ;; Advance to the next line. 1336 (search-forward ": ")
1329 (if (eolp) 1337 (setq thisfilename (buffer-substring beg (- (point) 2)))
1330 (forward-line 1)) 1338 (setq thisfilepos (read (current-buffer)))
1331 (if (> thisfilepos nodepos) 1339 ;; read in version 19 stops at the end of number.
1332 (throw 'foo t)) 1340 ;; Advance to the next line.
1333 (setq lastfilename thisfilename) 1341 (if (eolp)
1334 (setq lastfilepos thisfilepos)) 1342 (forward-line 1))
1335 (throw 'foo t)))) 1343 (if (> thisfilepos nodepos)
1336 (set-buffer (get-buffer "*info*")) 1344 (throw 'foo t))
1345 (setq lastfilename thisfilename)
1346 (setq lastfilepos thisfilepos))
1347 (throw 'foo t)))))
1337 (or (equal Info-current-subfile lastfilename) 1348 (or (equal Info-current-subfile lastfilename)
1338 (let ((buffer-read-only nil)) 1349 (let ((buffer-read-only nil))
1339 (setq buffer-file-name nil) 1350 (setq buffer-file-name nil)
1340 (widen) 1351 (widen)
1341 (erase-buffer) 1352 (erase-buffer)
1565 (setq bufs (cdr bufs))) 1576 (setq bufs (cdr bufs)))
1566 (setq Info-current-annotation-completions compl))))) 1577 (setq Info-current-annotation-completions compl)))))
1567 1578
1568 (defun Info-build-node-completions () 1579 (defun Info-build-node-completions ()
1569 (or Info-current-file-completions 1580 (or Info-current-file-completions
1570 (let ((compl (Info-build-annotation-completions))) 1581 (let ((m Info-tag-table-marker)
1582 (compl (Info-build-annotation-completions)))
1571 (save-excursion 1583 (save-excursion
1572 (save-restriction 1584 (save-restriction
1573 (widen) 1585 (widen)
1574 (if (marker-buffer Info-tag-table-marker) 1586 (if (marker-buffer Info-tag-table-marker)
1575 (progn 1587 (progn
1576 (set-buffer (marker-buffer Info-tag-table-marker)) 1588 (set-buffer (marker-buffer Info-tag-table-marker))
1577 (goto-char Info-tag-table-marker) 1589 (goto-char m)
1578 (while (re-search-forward "\nNode: \\(.*\\)\177" nil t) 1590 (while (re-search-forward "\nNode: \\(.*\\)\177" nil t)
1579 (setq compl 1591 (setq compl
1580 (cons (list (buffer-substring (match-beginning 1) 1592 (cons (list (buffer-substring (match-beginning 1)
1581 (match-end 1))) 1593 (match-end 1)))
1582 compl)))) 1594 compl))))
1585 (forward-line 1) 1597 (forward-line 1)
1586 (let ((beg (point))) 1598 (let ((beg (point)))
1587 (forward-line 1) 1599 (forward-line 1)
1588 (if (re-search-backward "Node: *\\([^,\n]*\\) *[,\n\t]" 1600 (if (re-search-backward "Node: *\\([^,\n]*\\) *[,\n\t]"
1589 beg t) 1601 beg t)
1590 (setq compl 1602 (setq compl
1591 (cons (list (buffer-substring (match-beginning 1) 1603 (cons (list (buffer-substring (match-beginning 1)
1592 (match-end 1))) 1604 (match-end 1)))
1593 compl)))))))) 1605 compl))))))))
1594 (setq Info-current-file-completions compl)))) 1606 (setq Info-current-file-completions compl))))
1595 1607
1623 (progn (re-search-forward regexp) (setq found (point))) 1635 (progn (re-search-forward regexp) (setq found (point)))
1624 (search-failed nil))))) 1636 (search-failed nil)))))
1625 (if (not found) ;can only happen in subfile case -- else would have erred 1637 (if (not found) ;can only happen in subfile case -- else would have erred
1626 (unwind-protect 1638 (unwind-protect
1627 (let ((list ())) 1639 (let ((list ()))
1628 (set-buffer (marker-buffer Info-tag-table-marker)) 1640 (save-excursion
1629 (goto-char (point-min)) 1641 (set-buffer (marker-buffer Info-tag-table-marker))
1630 (search-forward "\n\^_\nIndirect:") 1642 (goto-char (point-min))
1631 (save-restriction 1643 (search-forward "\n\^_\nIndirect:")
1632 (narrow-to-region (point) 1644 (save-restriction
1633 (progn (search-forward "\n\^_") 1645 (narrow-to-region (point)
1634 (1- (point)))) 1646 (progn (search-forward "\n\^_")
1635 (goto-char (point-min)) 1647 (1- (point))))
1636 (search-forward (concat "\n" osubfile ": ")) 1648 (goto-char (point-min))
1637 (beginning-of-line) 1649 (search-forward (concat "\n" osubfile ": "))
1638 (while (not (eobp)) 1650 (beginning-of-line)
1639 (re-search-forward "\\(^.*\\): [0-9]+$") 1651 (while (not (eobp))
1640 (goto-char (+ (match-end 1) 2)) 1652 (re-search-forward "\\(^.*\\): [0-9]+$")
1641 (setq list (cons (cons (read (current-buffer)) 1653 (goto-char (+ (match-end 1) 2))
1642 (buffer-substring (match-beginning 1) 1654 (setq list (cons (cons (read (current-buffer))
1643 (match-end 1))) 1655 (buffer-substring (match-beginning 1)
1644 list)) 1656 (match-end 1)))
1645 (goto-char (1+ (match-end 0)))) 1657 list))
1646 (setq list (nreverse list) 1658 (goto-char (1+ (match-end 0))))
1647 list (cdr list))) 1659 (setq list (nreverse list)
1660 list (cdr list))))
1648 (while list 1661 (while list
1649 (message "Searching subfile %s..." (cdr (car list))) 1662 (message "Searching subfile %s..." (cdr (car list)))
1650 (Info-read-subfile (car (car list))) 1663 (Info-read-subfile (car (car list)))
1651 (setq list (cdr list)) 1664 (setq list (cdr list))
1652 (goto-char (point-min)) 1665 (goto-char (point-min))
1665 (or (and (equal onode Info-current-node) 1678 (or (and (equal onode Info-current-node)
1666 (equal ofile Info-current-file)) 1679 (equal ofile Info-current-file))
1667 (Info-history-add ofile onode opoint))))) 1680 (Info-history-add ofile onode opoint)))))
1668 1681
1669 ;; Extract the value of the node-pointer named NAME. 1682 ;; Extract the value of the node-pointer named NAME.
1670 ;; If there is none, use ERRORNAME in the error message; 1683 ;; If there is none, use ERRORNAME in the error message;
1671 ;; if ERRORNAME is nil, just return nil. 1684 ;; if ERRORNAME is nil, just return nil.
1672 (defun Info-extract-pointer (name &optional errorname) 1685 (defun Info-extract-pointer (name &optional errorname)
1673 (save-excursion 1686 (save-excursion
1674 (goto-char (point-min)) 1687 (goto-char (point-min))
1675 (forward-line 4) 1688 (forward-line 4)
1941 (setq item nil)))) 1954 (setq item nil))))
1942 (list item)))) 1955 (list item))))
1943 ;; there is a problem here in that if several menu items have the same 1956 ;; there is a problem here in that if several menu items have the same
1944 ;; name you can only go to the node of the first with this command. 1957 ;; name you can only go to the node of the first with this command.
1945 (Info-goto-node (Info-extract-menu-item menu-item) nil t)) 1958 (Info-goto-node (Info-extract-menu-item menu-item) nil t))
1946 1959
1947 (defun Info-extract-menu-item (menu-item &optional noerror) 1960 (defun Info-extract-menu-item (menu-item &optional noerror)
1948 (save-excursion 1961 (save-excursion
1949 (goto-char (point-min)) 1962 (goto-char (point-min))
1950 (if (let ((case-fold-search t)) 1963 (if (let ((case-fold-search t))
1951 (search-forward "\n* menu:" nil t)) 1964 (search-forward "\n* menu:" nil t))
2290 ;;;###autoload 2303 ;;;###autoload
2291 (defun Info-elisp-ref (func) 2304 (defun Info-elisp-ref (func)
2292 "Look up an Emacs Lisp function in the Elisp manual in the Info system. 2305 "Look up an Emacs Lisp function in the Elisp manual in the Info system.
2293 This command is designed to be used whether you are already in Info or not." 2306 This command is designed to be used whether you are already in Info or not."
2294 (interactive (let ((fn (function-at-point)) 2307 (interactive (let ((fn (function-at-point))
2295 (enable-recursive-minibuffers t) 2308 (enable-recursive-minibuffers t)
2296 val) 2309 val)
2297 (setq val (completing-read 2310 (setq val (completing-read
2298 (format "Look up Emacs Lisp function%s: " 2311 (format "Look up Emacs Lisp function%s: "
2299 (if fn 2312 (if fn
2300 (format " (default %s)" fn) 2313 (format " (default %s)" fn)
2811 ; (setq buffer-mouse-map Info-mode-mouse-map) 2824 ; (setq buffer-mouse-map Info-mode-mouse-map)
2812 (make-local-variable 'Info-current-file) 2825 (make-local-variable 'Info-current-file)
2813 (make-local-variable 'Info-current-subfile) 2826 (make-local-variable 'Info-current-subfile)
2814 (make-local-variable 'Info-current-node) 2827 (make-local-variable 'Info-current-node)
2815 (make-local-variable 'Info-tag-table-marker) 2828 (make-local-variable 'Info-tag-table-marker)
2829 (setq Info-tag-table-marker (make-marker))
2830 (make-local-variable 'Info-tag-table-buffer)
2831 (setq Info-tag-table-buffer nil)
2816 (make-local-variable 'Info-current-file-completions) 2832 (make-local-variable 'Info-current-file-completions)
2817 (make-local-variable 'Info-current-annotation-completions) 2833 (make-local-variable 'Info-current-annotation-completions)
2818 (make-local-variable 'Info-index-alternatives) 2834 (make-local-variable 'Info-index-alternatives)
2819 (make-local-variable 'Info-history) 2835 (make-local-variable 'Info-history)
2820 ;; Faces are now defined by `defface'... 2836 ;; Faces are now defined by `defface'...
2876 (defun Info-cease-edit () 2892 (defun Info-cease-edit ()
2877 "Finish editing Info node; switch back to Info proper." 2893 "Finish editing Info node; switch back to Info proper."
2878 (interactive) 2894 (interactive)
2879 ;; Do this first, so nothing has changed if user C-g's at query. 2895 ;; Do this first, so nothing has changed if user C-g's at query.
2880 (and (buffer-modified-p) 2896 (and (buffer-modified-p)
2881 (y-or-n-p-maybe-dialog-box "Save the file? ") 2897 (y-or-n-p "Save the file? ")
2882 (save-buffer)) 2898 (save-buffer))
2883 (use-local-map Info-mode-map) 2899 (use-local-map Info-mode-map)
2884 (setq major-mode 'Info-mode) 2900 (setq major-mode 'Info-mode)
2885 (setq mode-name "Info") 2901 (setq mode-name "Info")
2886 (Info-set-mode-line) 2902 (Info-set-mode-line)
2997 "Construct a menu of Info commands. 3013 "Construct a menu of Info commands.
2998 Adds an entry for the node at EVENT, or under point if EVENT is omitted. 3014 Adds an entry for the node at EVENT, or under point if EVENT is omitted.
2999 Used to construct the menubar submenu and popup menu." 3015 Used to construct the menubar submenu and popup menu."
3000 (or event (setq event (point))) 3016 (or event (setq event (point)))
3001 (let ((case-fold-search t) 3017 (let ((case-fold-search t)
3002 (xref-regexp (concat "\\*" 3018 (xref-regexp (concat "\\*"
3003 (regexp-quote Info-footnote-tag) 3019 (regexp-quote Info-footnote-tag)
3004 "[ \n\t]*\\([^:]*\\):")) 3020 "[ \n\t]*\\([^:]*\\):"))
3005 up-p prev-p next-p menu xrefs subnodes in) 3021 up-p prev-p next-p menu xrefs subnodes in)
3006 (save-excursion 3022 (save-excursion
3007 ;; `one-space' fixes "Notes:" xrefs that are split across lines. 3023 ;; `one-space' fixes "Notes:" xrefs that are split across lines.