comparison lisp/info.el @ 412:697ef44129c6 r21-2-14

Import from CVS: tag r21-2-14
author cvs
date Mon, 13 Aug 2007 11:20:41 +0200
parents de805c49cfc1
children da8ed4261e83
comparison
equal deleted inserted replaced
411:12e008d41344 412:697ef44129c6
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 <didier@xemacs.org> 311 ;; Modified 1998-09-23 by Didier Verna <verna@inf.enst.fr>
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 'never 416 (defcustom Info-save-auto-generated-dir nil
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)
435 ;;;###autoload 435 ;;;###autoload
436 (defvar Info-directory-list nil 436 (defvar Info-directory-list nil
437 "List of directories to search for Info documentation files. 437 "List of directories to search for Info documentation files.
438 438
439 The first directory in this list, the \"dir\" file there will become 439 The first directory in this list, the \"dir\" file there will become
440 the (dir)Top node of the Info documentation tree. 440 the (dir)Top node of the Info documentation tree. If you wish to
441 441 modify the info search path, use `M-x customize-variable,
442 Note: DO NOT use the `customize' interface to change the value of this 442 Info-directory-list' to do so.")
443 variable. Its value is created dynamically on each startup, depending
444 on XEmacs packages installed on the system. If you want to change the
445 search path, make the needed modifications on the variable's value
446 from .emacs. For instance:
447
448 (setq Info-directory-list (cons \"~/info\" Info-directory-list))")
449 443
450 (defcustom Info-localdir-heading-regexp 444 (defcustom Info-localdir-heading-regexp
451 "^Locally installed XEmacs Packages:?" 445 "^Locally installed XEmacs Packages:?"
452 "The menu part of localdir files will be inserted below this topic 446 "The menu part of localdir files will be inserted below this topic
453 heading." 447 heading."
461 (defface info-xref '((t (:bold t))) 455 (defface info-xref '((t (:bold t)))
462 "Face used for cross-references in info." 456 "Face used for cross-references in info."
463 :group 'info-faces) 457 :group 'info-faces)
464 458
465 ;; Is this right for NT? .zip, with -c for to stdout, right? 459 ;; Is this right for NT? .zip, with -c for to stdout, right?
466 (defvar Info-suffix-list '( ("" . nil) 460 (defvar Info-suffix-list '( ("" . nil)
467 (".info" . nil) 461 (".info" . nil)
468 (".info.bz2" . "bzip2 -dc %s")
469 (".info.gz" . "gzip -dc %s") 462 (".info.gz" . "gzip -dc %s")
470 (".info-z" . "gzip -dc %s") 463 (".info-z" . "gzip -dc %s")
471 (".info.Z" . "uncompress -c %s") 464 (".info.Z" . "uncompress -c %s")
472 (".bz2" . "bzip2 -dc %s") 465 (".bz2" . "bzip2 -dc %s")
473 (".gz" . "gzip -dc %s") 466 (".gz" . "gzip -dc %s")
506 499
507 (defvar Info-index-alternatives nil 500 (defvar Info-index-alternatives nil
508 "List of possible matches for last Info-index command.") 501 "List of possible matches for last Info-index command.")
509 (defvar Info-index-first-alternative nil) 502 (defvar Info-index-first-alternative nil)
510 503
511 (defcustom Info-annotations-path 504 (defcustom Info-annotations-path '("~/.xemacs/info.notes"
512 (list 505 "~/.infonotes"
513 (paths-construct-path (list user-init-directory "info.notes")) 506 "/usr/lib/info.notes")
514 (paths-construct-path '("~" ".infonotes"))
515 (paths-construct-path '("usr" "lib" "info.notes")
516 (char-to-string directory-sep-char)))
517 "*Names of files that contain annotations for different Info nodes. 507 "*Names of files that contain annotations for different Info nodes.
518 By convention, the first one should reside in your personal directory. 508 By convention, the first one should reside in your personal directory.
519 The last should be a world-writable \"public\" annotations file." 509 The last should be a world-writable \"public\" annotations file."
520 :type '(repeat file) 510 :type '(repeat file)
521 :group 'info) 511 :group 'info)
535 This is the file .../info/dir, which contains the topmost node of the 525 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 526 Info hierarchy. The first time you invoke Info you start off
537 looking at that node, which is (dir)Top. 527 looking at that node, which is (dir)Top.
538  528 
539 File: dir Node: Top This is the top of the INFO tree 529 File: dir Node: Top This is the top of the INFO tree
540 This (the Directory node) gives a menu of major topics. 530 This (the Directory node) gives a menu of major topics.
541 531
542 * Menu: The list of major topics begins on the next line. 532 * Menu: The list of major topics begins on the next line.
543 533
544 ") 534 ")
545 535
590 (while f 580 (while f
591 (if (and (file-exists-p (car f)) (not (get-file-buffer (car f)))) 581 (if (and (file-exists-p (car f)) (not (get-file-buffer (car f))))
592 (bury-buffer (find-file-noselect (car f)))) 582 (bury-buffer (find-file-noselect (car f))))
593 (setq f (cdr f))))) 583 (setq f (cdr f)))))
594 584
595 ;;;###autoload
596 (defun Info-find-node (filename &optional nodename no-going-back tryfile line) 585 (defun Info-find-node (filename &optional nodename no-going-back tryfile line)
597 "Go to an info node specified as separate FILENAME and NODENAME. 586 "Go to an info node specified as separate FILENAME and NODENAME.
598 Look for a plausible filename, or if not found then look for URL's and 587 Look for a plausible filename, or if not found then look for URL's and
599 dispatch to the appropriate fn. NO-GOING-BACK is non-nil if 588 dispatch to the appropriate fn. NO-GOING-BACK is non-nil if
600 recovering from an error in this function; it says do not attempt 589 recovering from an error in this function; it says do not attempt
606 ;; empty filename is simple case 595 ;; empty filename is simple case
607 ((null filename) 596 ((null filename)
608 (Info-find-file-node nil nodename no-going-back tryfile line)) 597 (Info-find-file-node nil nodename no-going-back tryfile line))
609 ;; Convert filename to lower case if not found as specified. 598 ;; Convert filename to lower case if not found as specified.
610 ;; Expand it, look harder... 599 ;; Expand it, look harder...
611 ((let (temp temp-downcase found 600 ((let (temp temp-downcase found
612 (fname (substitute-in-file-name filename))) 601 (fname (substitute-in-file-name filename)))
613 (let ((dirs (cond 602 (let ((dirs (cond
614 ((string-match "^\\./" fname) ; If specified name starts with `./' 603 ((string-match "^\\./" fname) ; If specified name starts with `./'
615 (list default-directory)) ; then just try current directory. 604 (list default-directory)) ; then just try current directory.
616 ((file-name-absolute-p fname) 605 ((file-name-absolute-p fname)
627 (if (equal temp-downcase temp) (setq temp-downcase nil)) 616 (if (equal temp-downcase temp) (setq temp-downcase nil))
628 ;; Try several variants of specified name. 617 ;; Try several variants of specified name.
629 ;; Try downcasing, appending a suffix, or both. 618 ;; Try downcasing, appending a suffix, or both.
630 (setq found (Info-suffixed-file temp temp-downcase)) 619 (setq found (Info-suffixed-file temp temp-downcase))
631 (setq dirs (cdr dirs))) 620 (setq dirs (cdr dirs)))
632 (if found 621 (if found
633 (progn (setq filename (expand-file-name found)) 622 (progn (setq filename (expand-file-name found))
634 t)))) 623 t))))
635 (Info-find-file-node filename nodename no-going-back tryfile line)) 624 (Info-find-file-node filename nodename no-going-back tryfile line))
636 ;; Look for a URL. This pattern is stolen from w3.el to prevent 625 ;; Look for a URL. This pattern is stolen from w3.el to prevent
637 ;; loading it if we won't need it. 626 ;; loading it if we won't need it.
869 (set-buffer (or buf 858 (set-buffer (or buf
870 (generate-new-buffer 859 (generate-new-buffer
871 (if (string-match "localdir" file) 860 (if (string-match "localdir" file)
872 "localdir" 861 "localdir"
873 "info dir")))) 862 "info dir"))))
874 (if (not buf) 863 (if (not buf)
875 (insert-file-contents file)) 864 (insert-file-contents file))
876 (if (string-match "localdir" (buffer-name)) 865 (if (string-match "localdir" (buffer-name))
877 (setq lbuffers (cons (current-buffer) lbuffers)) 866 (setq lbuffers (cons (current-buffer) lbuffers))
878 (setq buffers (cons (current-buffer) buffers))) 867 (setq buffers (cons (current-buffer) buffers)))
879 (if attrs 868 (if attrs
880 (setq Info-dir-file-attributes 869 (setq Info-dir-file-attributes
881 (cons (cons file attrs) 870 (cons (cons file attrs)
882 Info-dir-file-attributes))))))) 871 Info-dir-file-attributes)))))))
883 (or (cdr dirs) (setq Info-dir-contents-directory (car dirs))) 872 (or (cdr dirs) (setq Info-dir-contents-directory (car dirs)))
884 (setq dirs (cdr dirs)))) 873 (setq dirs (cdr dirs))))
885 874
886 ;; ensure that the localdir files are inserted last, and reverse 875 ;; ensure that the localdir files are inserted last, and reverse
887 ;; the list of them so that when they get pushed in, they appear 876 ;; the list of them so that when they get pushed in, they appear
888 ;; in the same order they got specified in the path, from top to 877 ;; in the same order they got specified in the path, from top to
889 ;; bottom. 878 ;; bottom.
890 (nconc buffers (reverse lbuffers)) 879 (nconc buffers (reverse lbuffers))
891 880
892 (or buffers 881 (or buffers
893 (error "Can't find the Info directory node")) 882 (error "Can't find the Info directory node"))
894 ;; Distinguish the dir file that comes with Emacs from all the 883 ;; Distinguish the dir file that comes with Emacs from all the
895 ;; others. Yes, that is really what this is supposed to do. 884 ;; others. Yes, that is really what this is supposed to do.
896 ;; If it doesn't work, fix it. 885 ;; If it doesn't work, fix it.
955 (search-forward "\n\^_" nil 'move) 944 (search-forward "\n\^_" nil 'move)
956 (beginning-of-line) 945 (beginning-of-line)
957 (setq end (point)) 946 (setq end (point))
958 (setq nodes (cons (list nodename other beg end) nodes)))))) 947 (setq nodes (cons (list nodename other beg end) nodes))))))
959 (setq others (cdr others)))) 948 (setq others (cdr others))))
960 949
961 ;; Add to the main menu a menu item for each other node. 950 ;; Add to the main menu a menu item for each other node.
962 (re-search-forward "^\\* Menu:" nil t) 951 (re-search-forward "^\\* Menu:" nil t)
963 (forward-line 1) 952 (forward-line 1)
964 (let ((menu-items '("top")) 953 (let ((menu-items '("top"))
965 (nodes nodes) 954 (nodes nodes)
1015 (unless (or (not (file-exists-p (file-name-directory file))) 1004 (unless (or (not (file-exists-p (file-name-directory file)))
1016 (null (directory-files (file-name-directory file) nil "\\.info"))) 1005 (null (directory-files (file-name-directory file) nil "\\.info")))
1017 (if (not (find-buffer-visiting file)) 1006 (if (not (find-buffer-visiting file))
1018 (if (not (file-exists-p file)) 1007 (if (not (file-exists-p file))
1019 (if (or (eq Info-auto-generate-directory 'always) 1008 (if (or (eq Info-auto-generate-directory 'always)
1020 (eq Info-auto-generate-directory 'if-missing)) 1009 (eq Info-auto-generate-directory 'if-missing))
1021 (Info-build-dir-anew (file-name-directory file))) 1010 (Info-build-dir-anew (file-name-directory file)))
1022 (if (or (eq Info-auto-generate-directory 'always) 1011 (if (or (eq Info-auto-generate-directory 'always)
1023 (and (eq Info-auto-generate-directory 'if-outdated) 1012 (and (eq Info-auto-generate-directory 'if-outdated)
1024 (Info-dir-outdated-p file))) 1013 (Info-dir-outdated-p file)))
1025 (Info-rebuild-dir file)))))) 1014 (Info-rebuild-dir file))))))
1033 directory has been modified more recently." 1022 directory has been modified more recently."
1034 (let ((dir-mod-time (nth 5 (file-attributes file))) 1023 (let ((dir-mod-time (nth 5 (file-attributes file)))
1035 f-mod-time 1024 f-mod-time
1036 newer) 1025 newer)
1037 (setq Info-dir-newer-info-files nil) 1026 (setq Info-dir-newer-info-files nil)
1038 (mapcar 1027 (mapcar
1039 #'(lambda (f) 1028 #'(lambda (f)
1040 (prog2 1029 (prog2
1041 (setq f-mod-time (nth 5 (file-attributes f))) 1030 (setq f-mod-time (nth 5 (file-attributes f)))
1042 (setq newer (or (> (car f-mod-time) (car dir-mod-time)) 1031 (setq newer (or (> (car f-mod-time) (car dir-mod-time))
1043 (and (= (car f-mod-time) (car dir-mod-time)) 1032 (and (= (car f-mod-time) (car dir-mod-time))
1044 (> (car (cdr f-mod-time)) (car (cdr dir-mod-time)))))) 1033 (> (car (cdr f-mod-time)) (car (cdr dir-mod-time))))))
1045 (if (and (file-readable-p f) 1034 (if (and (file-readable-p f)
1046 newer) 1035 newer)
1047 (setq Info-dir-newer-info-files 1036 (setq Info-dir-newer-info-files
1048 (cons f Info-dir-newer-info-files))))) 1037 (cons f Info-dir-newer-info-files)))))
1049 (directory-files (file-name-directory file) 1038 (directory-files (file-name-directory file)
1050 'fullname 1039 'fullname
1051 ".*\\.info\\(\\.gz\\|\\.bz2\\|\\.Z\\|-z\\|\\.zip\\)?$" 1040 ".*\\.info\\(\\.gz\\|\\.bz2\\|\\.Z\\|-z\\|\\.zip\\)?$"
1052 'nosort 1041 'nosort
1081 (while (re-search-forward "^\\* \\([^:]+\\):\\([ \t]*(\\([^)]*\\))\\w*\\.\\|:\\)" nil t) 1070 (while (re-search-forward "^\\* \\([^:]+\\):\\([ \t]*(\\([^)]*\\))\\w*\\.\\|:\\)" nil t)
1082 (setq entry (list (match-string 2) 1071 (setq entry (list (match-string 2)
1083 (match-string 1) 1072 (match-string 1)
1084 (downcase (or (match-string 3) 1073 (downcase (or (match-string 3)
1085 (match-string 1))))) 1074 (match-string 1)))))
1086 (setq entry 1075 (setq entry
1087 (cons (nreverse 1076 (cons (nreverse
1088 (cdr 1077 (cdr
1089 (nreverse 1078 (nreverse
1090 (split-string 1079 (split-string
1091 (buffer-substring 1080 (buffer-substring
1092 (re-search-forward "[ \t]*" nil t) 1081 (re-search-forward "[ \t]*" nil t)
1093 (or (and (re-search-forward "^[^ \t]" nil t) 1082 (or (and (re-search-forward "^[^ \t]" nil t)
1094 (goto-char (match-beginning 0))) 1083 (goto-char (match-beginning 0)))
1095 (point-max))) 1084 (point-max)))
1096 "[ \t]*\n[ \t]*")))) 1085 "[ \t]*\n[ \t]*"))))
1107 (setq len (length (concat (car e) 1096 (setq len (length (concat (car e)
1108 (car (cdr e))))) 1097 (car (cdr e)))))
1109 (if (> len description-col) 1098 (if (> len description-col)
1110 (setq description-col len))) 1099 (setq description-col len)))
1111 entries) 1100 entries)
1112 (setq description-col (+ 5 description-col)) 1101 (setq description-col (+ 5 description-col))
1113 (mapcar #'(lambda (e) 1102 (mapcar #'(lambda (e)
1114 (setq e (cdr e)) ; Drop filename 1103 (setq e (cdr e)) ; Drop filename
1115 (insert "* " (car e) ":" (car (cdr e))) 1104 (insert "* " (car e) ":" (car (cdr e)))
1116 (setq e (car (cdr (cdr e)))) 1105 (setq e (car (cdr (cdr e))))
1117 (while e 1106 (while e
1122 (insert "\n"))) 1111 (insert "\n")))
1123 1112
1124 1113
1125 (defun Info-build-dir-anew (directory) 1114 (defun Info-build-dir-anew (directory)
1126 "Build info directory information for DIRECTORY. 1115 "Build info directory information for DIRECTORY.
1127 The generated directory listing may be saved to a `dir' according 1116 The generated directory listing may be saved to a `dir' according
1128 to the value of `Info-save-auto-generated-dir'" 1117 to the value of `Info-save-auto-generated-dir'"
1129 (save-excursion 1118 (save-excursion
1130 (let* ((dirfile (expand-file-name "dir" directory)) 1119 (let* ((dirfile (expand-file-name "dir" directory))
1131 (to-temp (or (null Info-save-auto-generated-dir) 1120 (to-temp (or (null Info-save-auto-generated-dir)
1132 (eq Info-save-auto-generated-dir 'never) 1121 (eq Info-save-auto-generated-dir 'never)
1133 (and (not (file-writable-p dirfile)) 1122 (and (not (file-writable-p dirfile))
1134 (message "File not writable %s. Using temporary." dirfile)))) 1123 (message "File not writable %s. Using temporary." dirfile))))
1135 (info-files 1124 (info-files
1136 (directory-files directory 1125 (directory-files directory
1137 'fullname 1126 'fullname
1138 ".*\\.info\\(.gz\\|.Z\\|-z\\|.zip\\)?$" 1127 ".*\\.info\\(.gz\\|.Z\\|-z\\|.zip\\)?$"
1139 nil 1128 nil
1140 t))) 1129 t)))
1144 (set-buffer (find-file-noselect dirfile t)) 1133 (set-buffer (find-file-noselect dirfile t))
1145 (setq buffer-read-only nil) 1134 (setq buffer-read-only nil)
1146 (erase-buffer) 1135 (erase-buffer)
1147 (insert Info-dir-prologue 1136 (insert Info-dir-prologue
1148 "Info files in " directory ":\n\n") 1137 "Info files in " directory ":\n\n")
1149 (Info-dump-dir-entries 1138 (Info-dump-dir-entries
1150 (mapcar 1139 (mapcar
1151 #'(lambda (f) 1140 #'(lambda (f)
1152 (or (Info-extract-dir-entry-from f) 1141 (or (Info-extract-dir-entry-from f)
1153 (list 'dummy 1142 (list 'dummy
1154 (progn 1143 (progn
1155 (string-match "\\(.*\\)\\.info\\(.gz\\|.Z\\|-z\\|.zip\\)?$" 1144 (string-match "\\(.*\\)\\.info\\(.gz\\|.Z\\|-z\\|.zip\\)?$"
1156 (file-name-nondirectory f)) 1145 (file-name-nondirectory f))
1157 (capitalize (match-string 1 (file-name-nondirectory f)))) 1146 (capitalize (match-string 1 (file-name-nondirectory f))))
1158 ":" 1147 ":"
1159 (list Info-no-description-string)))) 1148 (list Info-no-description-string))))
1160 info-files)) 1149 info-files))
1166 (message "Creating %s...done" dirfile))))) 1155 (message "Creating %s...done" dirfile)))))
1167 1156
1168 1157
1169 (defun Info-rebuild-dir (file) 1158 (defun Info-rebuild-dir (file)
1170 "Build info directory information in the directory of dir FILE. 1159 "Build info directory information in the directory of dir FILE.
1171 Description of info files are merged from the info files in the 1160 Description of info files are merged from the info files in the
1172 directory and the contents of FILE with the description in info files 1161 directory and the contents of FILE with the description in info files
1173 taking precedence over descriptions in FILE. 1162 taking precedence over descriptions in FILE.
1174 The generated directory listing may be saved to a `dir' according to 1163 The generated directory listing may be saved to a `dir' according to
1175 the value of `Info-save-auto-generated-dir' " 1164 the value of `Info-save-auto-generated-dir' "
1176 (save-excursion 1165 (save-excursion
1177 (save-restriction 1166 (save-restriction
1178 (let (dir-section-contents dir-full-contents 1167 (let (dir-section-contents dir-full-contents
1179 dir-entry 1168 dir-entry
1180 file-dir-entry 1169 file-dir-entry
1181 mark next-section 1170 mark next-section
1182 not-first-section 1171 not-first-section
1183 (to-temp 1172 (to-temp
1184 (or (null Info-save-auto-generated-dir) 1173 (or (null Info-save-auto-generated-dir)
1185 (eq Info-save-auto-generated-dir 'never) 1174 (eq Info-save-auto-generated-dir 'never)
1186 (and (eq Info-save-auto-generated-dir 'always) 1175 (and (eq Info-save-auto-generated-dir 'always)
1187 (not (file-writable-p file)) 1176 (not (file-writable-p file))
1188 (message "File not writable %s. Using temporary." file)) 1177 (message "File not writable %s. Using temporary." file))
1189 (and (eq Info-save-auto-generated-dir 'conservative) 1178 (and (eq Info-save-auto-generated-dir 'conservative)
1190 (or (and (not (file-writable-p file)) 1179 (or (and (not (file-writable-p file))
1191 (message "File not writable %s. Using temporary." file)) 1180 (message "File not writable %s. Using temporary." file))
1192 (not (y-or-n-p 1181 (not (y-or-n-p
1193 (message "%s is outdated. Overwrite ? " 1182 (message "%s is outdated. Overwrite ? "
1194 file)))))))) 1183 file))))))))
1195 (set-buffer (find-file-noselect file t)) 1184 (set-buffer (find-file-noselect file t))
1196 (setq buffer-read-only nil) 1185 (setq buffer-read-only nil)
1197 (if to-temp 1186 (if to-temp
1198 (message "Rebuilding temporary %s..." file) 1187 (message "Rebuilding temporary %s..." file)
1231 (file-name-nondirectory file))) 1220 (file-name-nondirectory file)))
1232 dir-full-contents)) 1221 dir-full-contents))
1233 (if file-dir-entry 1222 (if file-dir-entry
1234 (setq dir-section-contents (cons file-dir-entry 1223 (setq dir-section-contents (cons file-dir-entry
1235 dir-section-contents)) 1224 dir-section-contents))
1236 (setq dir-section-contents 1225 (setq dir-section-contents
1237 (cons (list 'dummy 1226 (cons (list 'dummy
1238 (capitalize (file-name-sans-extension 1227 (capitalize (file-name-sans-extension
1239 (file-name-nondirectory file))) 1228 (file-name-nondirectory file)))
1240 ":" 1229 ":"
1241 (list Info-no-description-string)) 1230 (list Info-no-description-string))
1242 dir-section-contents)))))) 1231 dir-section-contents))))))
1243 Info-dir-newer-info-files) 1232 Info-dir-newer-info-files)
1244 (delete-region (point-min) (point-max)) 1233 (delete-region (point-min) (point-max))
1245 (Info-dump-dir-entries (nreverse dir-section-contents)) 1234 (Info-dump-dir-entries (nreverse dir-section-contents))
1246 (widen) 1235 (widen)
1258 (set-buffer-modified-p nil) 1247 (set-buffer-modified-p nil)
1259 (message "Rebuilding temporary %s...done" file)) 1248 (message "Rebuilding temporary %s...done" file))
1260 (save-buffer) 1249 (save-buffer)
1261 (message "Rebuilding %s...done" file)))))) 1250 (message "Rebuilding %s...done" file))))))
1262 1251
1263 ;;;###autoload 1252 ;;;###autoload
1264 (defun Info-batch-rebuild-dir () 1253 (defun Info-batch-rebuild-dir ()
1265 "(Re)build info `dir' files in the directories remaining on the command line. 1254 "(Re)build info `dir' files in the directories remaining on the command line.
1266 Use this from the command line, with `-batch'; 1255 Use this from the command line, with `-batch';
1267 it won't work in an interactive Emacs. 1256 it won't work in an interactive Emacs.
1268 Each file is processed even if an error occurred previously. 1257 Each file is processed even if an error occurred previously.
1278 (if (not (file-directory-p (car command-line-args-left))) 1267 (if (not (file-directory-p (car command-line-args-left)))
1279 (message "Warning: Skipped %s. Not a directory." 1268 (message "Warning: Skipped %s. Not a directory."
1280 (car command-line-args-left)) 1269 (car command-line-args-left))
1281 (setq dir (expand-file-name "dir" (car command-line-args-left))) 1270 (setq dir (expand-file-name "dir" (car command-line-args-left)))
1282 (setq localdir (expand-file-name "localdir" (car command-line-args-left))) 1271 (setq localdir (expand-file-name "localdir" (car command-line-args-left)))
1283 (cond 1272 (cond
1284 ((file-exists-p dir) 1273 ((file-exists-p dir)
1285 (Info-rebuild-dir dir)) 1274 (Info-rebuild-dir dir))
1286 ((file-exists-p localdir) 1275 ((file-exists-p localdir)
1287 (Info-rebuild-dir localdir)) 1276 (Info-rebuild-dir localdir))
1288 (t 1277 (t
1494 nil t nil 1483 nil t nil
1495 'Info-minibuffer-history))) 1484 'Info-minibuffer-history)))
1496 (or (equal tag "") (Info-find-node nil (format "<<%s>>" tag))))) 1485 (or (equal tag "") (Info-find-node nil (format "<<%s>>" tag)))))
1497 1486
1498 ;;;###autoload 1487 ;;;###autoload
1499 (defun Info-visit-file (file) 1488 (defun Info-visit-file ()
1500 "Directly visit an info file." 1489 "Directly visit an info file."
1501 (interactive "fVisit Info file: ") 1490 (interactive)
1502 (Info-find-node (expand-file-name file) "Top")) 1491 (let* ((insert-default-directory nil)
1492 (file (read-file-name "Goto Info file: " "" "")))
1493 (or (equal file "") (Info-find-node (expand-file-name file) "Top"))))
1503 1494
1504 (defun Info-restore-point (&optional always) 1495 (defun Info-restore-point (&optional always)
1505 "Restore point to same location it had last time we were in this node." 1496 "Restore point to same location it had last time we were in this node."
1506 (interactive "p") 1497 (interactive "p")
1507 (if (or Info-restoring-point always) 1498 (if (or Info-restoring-point always)
1516 (and (nth 2 entry) 1507 (and (nth 2 entry)
1517 (get-buffer-window (current-buffer)) 1508 (get-buffer-window (current-buffer))
1518 (set-window-start (get-buffer-window (current-buffer)) 1509 (set-window-start (get-buffer-window (current-buffer))
1519 (+ (nth 2 entry) (point-min))))) 1510 (+ (nth 2 entry) (point-min)))))
1520 1511
1521 (defvar Info-read-node-completion-table)
1522
1523 ;; This function is used as the "completion table" while reading a node name.
1524 ;; It does completion using the alist in Info-read-node-completion-table
1525 ;; unless STRING starts with an open-paren.
1526 (defun Info-read-node-name-1 (string predicate code)
1527 (let ((no-completion (and (> (length string) 0) (eq (aref string 0) ?\())))
1528 (cond ((eq code nil)
1529 (if no-completion
1530 string
1531 (try-completion string Info-read-node-completion-table predicate)))
1532 ((eq code t)
1533 (if no-completion
1534 nil
1535 (all-completions string Info-read-node-completion-table predicate)))
1536 ((eq code 'lambda)
1537 (if no-completion
1538 t
1539 (assoc string Info-read-node-completion-table))))))
1540
1541 (defun Info-read-node-name (prompt &optional default) 1512 (defun Info-read-node-name (prompt &optional default)
1542 (Info-setup-initial) 1513 (Info-setup-initial)
1543 (let* ((completion-ignore-case t) 1514 (let* ((completion-ignore-case t)
1544 (Info-read-node-completion-table (Info-build-node-completions)) 1515 (nodename (completing-read prompt
1545 (nodename (completing-read prompt 'Info-read-node-name-1 1516 (Info-build-node-completions)
1546 nil t nil 'Info-minibuffer-history 1517 nil nil nil
1547 default))) 1518 'Info-minibuffer-history)))
1548 (if (equal nodename "") 1519 (if (equal nodename "")
1549 (or default 1520 (or default
1550 (Info-read-node-name prompt)) 1521 (Info-read-node-name prompt))
1551 nodename))) 1522 nodename)))
1552 1523
1586 (forward-line 1) 1557 (forward-line 1)
1587 (let ((beg (point))) 1558 (let ((beg (point)))
1588 (forward-line 1) 1559 (forward-line 1)
1589 (if (re-search-backward "Node: *\\([^,\n]*\\) *[,\n\t]" 1560 (if (re-search-backward "Node: *\\([^,\n]*\\) *[,\n\t]"
1590 beg t) 1561 beg t)
1591 (setq compl 1562 (setq compl
1592 (cons (list (buffer-substring (match-beginning 1) 1563 (cons (list (buffer-substring (match-beginning 1)
1593 (match-end 1))) 1564 (match-end 1)))
1594 compl)))))))) 1565 compl))))))))
1595 (setq Info-current-file-completions compl)))) 1566 (setq Info-current-file-completions compl))))
1596 1567
1599 1570
1600 1571
1601 ;;;###autoload 1572 ;;;###autoload
1602 (defun Info-search (regexp) 1573 (defun Info-search (regexp)
1603 "Search for REGEXP, starting from point, and select node it's found in." 1574 "Search for REGEXP, starting from point, and select node it's found in."
1604 (interactive (list 1575 (interactive "sSearch (regexp): ")
1605 (read-from-minibuffer 1576 (if (equal regexp "")
1606 (if Info-last-search 1577 (setq regexp Info-last-search)
1607 (format "Search (regexp, default %s): " 1578 (setq Info-last-search regexp))
1608 Info-last-search)
1609 "Search (regexp): ")
1610 nil nil nil nil nil Info-last-search)))
1611 (setq Info-last-search regexp)
1612 (with-search-caps-disable-folding regexp t 1579 (with-search-caps-disable-folding regexp t
1613 (let ((found ()) 1580 (let ((found ())
1614 (onode Info-current-node) 1581 (onode Info-current-node)
1615 (ofile Info-current-file) 1582 (ofile Info-current-file)
1616 (opoint (point)) 1583 (opoint (point))
1666 (or (and (equal onode Info-current-node) 1633 (or (and (equal onode Info-current-node)
1667 (equal ofile Info-current-file)) 1634 (equal ofile Info-current-file))
1668 (Info-history-add ofile onode opoint))))) 1635 (Info-history-add ofile onode opoint)))))
1669 1636
1670 ;; Extract the value of the node-pointer named NAME. 1637 ;; Extract the value of the node-pointer named NAME.
1671 ;; If there is none, use ERRORNAME in the error message; 1638 ;; If there is none, use ERRORNAME in the error message;
1672 ;; if ERRORNAME is nil, just return nil. 1639 ;; if ERRORNAME is nil, just return nil.
1673 (defun Info-extract-pointer (name &optional errorname) 1640 (defun Info-extract-pointer (name &optional errorname)
1674 (save-excursion 1641 (save-excursion
1675 (goto-char (point-min)) 1642 (goto-char (point-min))
1676 (forward-line 4) 1643 (forward-line 4)
1683 nil 1650 nil
1684 (error (concat "Node has no " (capitalize (or errorname name))))))))) 1651 (error (concat "Node has no " (capitalize (or errorname name)))))))))
1685 1652
1686 ;; Return the node name in the buffer following point. 1653 ;; Return the node name in the buffer following point.
1687 ;; ALLOWEDCHARS, if non-nil, goes within [...] to make a regexp 1654 ;; ALLOWEDCHARS, if non-nil, goes within [...] to make a regexp
1688 ;; saying which chars may appear in the node name. 1655 ;; saying which chas may appear in the node name.
1689 (defun Info-following-node-name (&optional allowedchars) 1656 (defun Info-following-node-name (&optional allowedchars)
1690 (skip-chars-forward " \t") 1657 (skip-chars-forward " \t")
1691 (buffer-substring 1658 (buffer-substring
1692 (point) 1659 (point)
1693 (progn 1660 (progn
1694 (while (looking-at (concat "[" (or allowedchars "^,\t\n") "]")) 1661 (while (looking-at (concat "[" (or allowedchars "^,\t\n") "]"))
1695 (skip-chars-forward (concat (or allowedchars "^,\t\n") "(")) 1662 (skip-chars-forward (concat (or allowedchars "^,\t\n") "("))
1696 (if (looking-at "(") 1663 (if (looking-at "(")
1697 (skip-chars-forward "^)"))) 1664 (skip-chars-forward "^)")))
1698 (skip-chars-backward " .") 1665 (skip-chars-backward " ")
1699 (point)))) 1666 (point))))
1700 1667
1701 (defun Info-next (&optional n) 1668 (defun Info-next (&optional n)
1702 "Go to the next node of this node. 1669 "Go to the next node of this node.
1703 A positive or negative prefix argument moves by multiple nodes." 1670 A positive or negative prefix argument moves by multiple nodes."
1788 (let ((item (completing-read (if default 1755 (let ((item (completing-read (if default
1789 (concat "Follow reference named: (" 1756 (concat "Follow reference named: ("
1790 default ") ") 1757 default ") ")
1791 "Follow reference named: ") 1758 "Follow reference named: ")
1792 completions nil t nil 1759 completions nil t nil
1793 'Info-minibuffer-history 1760 'Info-minibuffer-history)))
1794 default)))
1795 (if (and (string= item "") default) 1761 (if (and (string= item "") default)
1796 (list default) 1762 (list default)
1797 (list item))) 1763 (list item)))
1798 (error "No cross-references in this node")))) 1764 (error "No cross-references in this node"))))
1799 (let (target i (str (concat "\\*" Info-footnote-tag " " 1765 (let (target i (str (concat "\\*" Info-footnote-tag " "
1873 (forward-char 1) 1839 (forward-char 1)
1874 (setq str 1840 (setq str
1875 (if (looking-at ":") 1841 (if (looking-at ":")
1876 (buffer-substring beg (1- (point))) 1842 (buffer-substring beg (1- (point)))
1877 (skip-chars-forward " \t\n") 1843 (skip-chars-forward " \t\n")
1878 ;; Kludge. 1844 (Info-following-node-name (if multi-line "^.,\t" "^.,\t\n"))))
1879 ;; Allow dots in node name not followed by whitespace.
1880 (re-search-forward
1881 (concat "\\(([^)]+)[^."
1882 (if multi-line "" "\n")
1883 "]*\\|\\([^.,\t"
1884 (if multi-line "" "\n")
1885 ;; We consider dots followed by newline as
1886 ;; end of nodename even if multil-line.
1887 ;; Also stops at .). It is generated by @pxref.
1888 ;; Skips sequential dots.
1889 "]\\|\\.+[^ \t\n)]\\)+\\)"))
1890 (match-string 1)))
1891 (while (setq i (string-match "\n" str i)) 1845 (while (setq i (string-match "\n" str i))
1892 (aset str i ?\ )) 1846 (aset str i ?\ ))
1893 str)) 1847 str))
1894 1848
1895 (defun Info-menu (menu-item) 1849 (defun Info-menu (menu-item)
1928 (completing-read (if default 1882 (completing-read (if default
1929 (format "Menu item (default %s): " 1883 (format "Menu item (default %s): "
1930 default) 1884 default)
1931 "Menu item: ") 1885 "Menu item: ")
1932 completions nil t nil 1886 completions nil t nil
1933 'Info-minibuffer-history 1887 'Info-minibuffer-history)))
1934 default)))
1935 ;; we rely on the fact that completing-read accepts an input 1888 ;; we rely on the fact that completing-read accepts an input
1936 ;; of "" even when the require-match argument is true and "" 1889 ;; of "" even when the require-match argument is true and ""
1937 ;; is not a valid possibility 1890 ;; is not a valid possibility
1938 (if (string= item "") 1891 (if (string= item "")
1939 (if default 1892 (if default
1942 (setq item nil)))) 1895 (setq item nil))))
1943 (list item)))) 1896 (list item))))
1944 ;; there is a problem here in that if several menu items have the same 1897 ;; there is a problem here in that if several menu items have the same
1945 ;; name you can only go to the node of the first with this command. 1898 ;; name you can only go to the node of the first with this command.
1946 (Info-goto-node (Info-extract-menu-item menu-item) nil t)) 1899 (Info-goto-node (Info-extract-menu-item menu-item) nil t))
1947 1900
1948 (defun Info-extract-menu-item (menu-item &optional noerror) 1901 (defun Info-extract-menu-item (menu-item &optional noerror)
1949 (save-excursion 1902 (save-excursion
1950 (goto-char (point-min)) 1903 (goto-char (point-min))
1951 (if (let ((case-fold-search t)) 1904 (if (let ((case-fold-search t))
1952 (search-forward "\n* menu:" nil t)) 1905 (search-forward "\n* menu:" nil t))
2105 (while (>= (setq n (1- n)) 0) 2058 (while (>= (setq n (1- n)) 0)
2106 (if (pos-visible-in-window-p (point-min)) 2059 (if (pos-visible-in-window-p (point-min))
2107 (progn 2060 (progn
2108 (Info-global-prev) 2061 (Info-global-prev)
2109 (message "Node: %s" Info-current-node) 2062 (message "Node: %s" Info-current-node)
2110 (goto-char (point-max)) 2063 (sit-for 0)
2111 (recenter -1) 2064 ;;(scroll-up 1) ; work around bug in pos-visible-in-window-p
2112 (move-to-window-line 0)) 2065 ;;(scroll-down 1)
2066 (while (not (pos-visible-in-window-p (point-max)))
2067 (scroll-up)))
2113 (scroll-down))))) 2068 (scroll-down)))))
2114 2069
2115 (defun Info-scroll-prev (arg) 2070 (defun Info-scroll-prev (arg)
2116 (interactive "P") 2071 (interactive "P")
2117 (if Info-auto-advance 2072 (if Info-auto-advance
2118 (if (and (pos-visible-in-window-p (point-min)) 2073 (if (and (pos-visible-in-window-p (point-min))
2119 (not (eq Info-auto-advance t)) 2074 (not (eq Info-auto-advance t))
2120 (not (eq last-command this-command))) 2075 (not (eq last-command this-command)))
2121 (message "Hit %s again to go to previous node" 2076 (message "Hit %s again to go to previous node"
2122 (if (mouse-event-p last-command-event) 2077 (if (= last-command-char 0)
2123 "mouse button" 2078 "mouse button"
2124 (key-description (event-key last-command-event)))) 2079 (key-description (char-to-string last-command-char))))
2125 (Info-page-prev) 2080 (Info-page-prev)
2126 (setq this-command 'Info)) 2081 (setq this-command 'Info))
2127 (scroll-down arg))) 2082 (scroll-down arg)))
2128 2083
2129 (defun Info-index (topic) 2084 (defun Info-index (topic)
2136 Use the `,' command to see the other matches. 2091 Use the `,' command to see the other matches.
2137 Give a blank topic name to go to the Index node itself." 2092 Give a blank topic name to go to the Index node itself."
2138 (interactive "sIndex topic: ") 2093 (interactive "sIndex topic: ")
2139 (let ((pattern (format "\n\\* \\([^\n:]*%s[^\n:]*\\):[ \t]*%s" 2094 (let ((pattern (format "\n\\* \\([^\n:]*%s[^\n:]*\\):[ \t]*%s"
2140 (regexp-quote topic) 2095 (regexp-quote topic)
2141 "\\(.*\\)\\.[ t]*\\([0-9]*\\)$")) 2096 "\\([^.\n]*\\)\\.[ t]*\\([0-9]*\\)"))
2142 node) 2097 node)
2143 (message "Searching index for `%s'..." topic) 2098 (message "Searching index for `%s'..." topic)
2144 (Info-goto-node "Top") 2099 (Info-goto-node "Top")
2145 (let ((case-fold-search t)) 2100 (let ((case-fold-search t))
2146 (or (search-forward "\n* menu:" nil t) 2101 (or (search-forward "\n* menu:" nil t)
2291 ;;;###autoload 2246 ;;;###autoload
2292 (defun Info-elisp-ref (func) 2247 (defun Info-elisp-ref (func)
2293 "Look up an Emacs Lisp function in the Elisp manual in the Info system. 2248 "Look up an Emacs Lisp function in the Elisp manual in the Info system.
2294 This command is designed to be used whether you are already in Info or not." 2249 This command is designed to be used whether you are already in Info or not."
2295 (interactive (let ((fn (function-at-point)) 2250 (interactive (let ((fn (function-at-point))
2296 (enable-recursive-minibuffers t) 2251 (enable-recursive-minibuffers t)
2297 val) 2252 val)
2298 (setq val (completing-read 2253 (setq val (completing-read
2299 (format "Look up Emacs Lisp function%s: " 2254 (format "Look up Emacs Lisp function%s: "
2300 (if fn 2255 (if fn
2301 (format " (default %s)" fn) 2256 (format " (default %s)" fn)
2998 "Construct a menu of Info commands. 2953 "Construct a menu of Info commands.
2999 Adds an entry for the node at EVENT, or under point if EVENT is omitted. 2954 Adds an entry for the node at EVENT, or under point if EVENT is omitted.
3000 Used to construct the menubar submenu and popup menu." 2955 Used to construct the menubar submenu and popup menu."
3001 (or event (setq event (point))) 2956 (or event (setq event (point)))
3002 (let ((case-fold-search t) 2957 (let ((case-fold-search t)
3003 (xref-regexp (concat "\\*" 2958 (xref-regexp (concat "\\*"
3004 (regexp-quote Info-footnote-tag) 2959 (regexp-quote Info-footnote-tag)
3005 "[ \n\t]*\\([^:]*\\):")) 2960 "[ \n\t]*\\([^:]*\\):"))
3006 up-p prev-p next-p menu xrefs subnodes in) 2961 up-p prev-p next-p menu xrefs subnodes in)
3007 (save-excursion 2962 (save-excursion
3008 ;; `one-space' fixes "Notes:" xrefs that are split across lines. 2963 ;; `one-space' fixes "Notes:" xrefs that are split across lines.