Mercurial > emacs
comparison lisp/info.el @ 2561:1bd4cf98df68
(Info-find-node, Info-insert-subfile): Do the right thing if info files have
been compressed or gzipped. This is saving me lots of disk space.
author | Eric S. Raymond <esr@snark.thyrsus.com> |
---|---|
date | Fri, 23 Apr 1993 02:20:55 +0000 |
parents | dd9ab1e9467e |
children | fa1b6b4e8409 |
comparison
equal
deleted
inserted
replaced
2560:50d7841854b3 | 2561:1bd4cf98df68 |
---|---|
64 "Name of node that Info is now looking at, or nil.") | 64 "Name of node that Info is now looking at, or nil.") |
65 | 65 |
66 (defvar Info-tag-table-marker (make-marker) | 66 (defvar Info-tag-table-marker (make-marker) |
67 "Marker pointing at beginning of current Info file's tag table. | 67 "Marker pointing at beginning of current Info file's tag table. |
68 Marker points nowhere if file has no tag table.") | 68 Marker points nowhere if file has no tag table.") |
69 | |
70 (defvar Info-index-alternatives nil | |
71 "List of possible matches for last Info-index command.") | |
72 | |
73 (defvar Info-suffix-list '( ("" . nil) | |
74 (".info" . nil) | |
75 (".Z" . "uncompress") | |
76 (".Y" . "unyabba") | |
77 (".z" . "gunzip") | |
78 (".info.Z" . "uncompress") | |
79 (".info.Y" . "unyabba") | |
80 (".z" . "gunzip")) | |
81 "List of file name suffixes and associated decoding commands. | |
82 Each entry should be (SUFFIX . STRING); the file is given to | |
83 the command as standard input. If STRING is nil, no decoding is done.") | |
84 | |
85 (defun info-insert-file-contents (filename &optional visit) | |
86 "Insert the contents of an info file in the current buffer. | |
87 Do the right thing if the file has been compressed or zipped." | |
88 (if (null (catch 'ok | |
89 (mapcar | |
90 (function | |
91 (lambda (x) | |
92 (let ((compressed (concat filename (car x)))) | |
93 (if (file-exists-p compressed) | |
94 (progn | |
95 (insert-file-contents compressed visit) | |
96 (if (cdr x) | |
97 (let ((buffer-read-only nil)) | |
98 (shell-command-on-region | |
99 (point-min) (point-max) (cdr x) t))) | |
100 (throw 'ok t)))))) | |
101 Info-suffix-list) | |
102 nil)) | |
103 (error "Can't find %s or any compressed version of it!" filename))) | |
69 | 104 |
70 ;;;###autoload | 105 ;;;###autoload |
71 (defun info (&optional file) | 106 (defun info (&optional file) |
72 "Enter Info, the documentation browser. | 107 "Enter Info, the documentation browser. |
73 Optional argument FILE specifies the file to examine; | 108 Optional argument FILE specifies the file to examine; |
116 (while (and dirs (not found)) | 151 (while (and dirs (not found)) |
117 (setq temp (expand-file-name filename (car dirs))) | 152 (setq temp (expand-file-name filename (car dirs))) |
118 (setq temp-downcase | 153 (setq temp-downcase |
119 (expand-file-name (downcase filename) (car dirs))) | 154 (expand-file-name (downcase filename) (car dirs))) |
120 ;; Try several variants of specified name. | 155 ;; Try several variants of specified name. |
121 ;; Try downcasing, appending `.info', or both. | 156 (catch 'foundit |
122 (cond ((file-exists-p temp) | 157 (mapcar |
123 (setq found temp)) | 158 (function |
124 ((file-exists-p temp-downcase) | 159 (lambda (x) |
125 (setq found temp-downcase)) | 160 (if (file-exists-p (concat temp (car x))) |
126 ((file-exists-p (concat temp ".info")) | 161 (progn |
127 (setq found (concat temp ".info"))) | 162 (setq found temp) |
128 ((file-exists-p (concat temp-downcase ".info")) | 163 (throw 'foundit nil))) |
129 (setq found (concat temp-downcase ".info")))) | 164 (if (file-exists-p (concat temp-downcase (car x))) |
165 (progn | |
166 (setq found temp-downcase) | |
167 (throw 'foundit nil))))) | |
168 Info-suffix-list)) | |
130 (setq dirs (cdr dirs))))) | 169 (setq dirs (cdr dirs))))) |
131 (if found | 170 (if found |
132 (setq filename found) | 171 (setq filename found) |
133 (error "Info file %s does not exist" filename)))) | 172 (error "Info file %s does not exist" filename)))) |
134 ;; Record the node we are leaving. | 173 ;; Record the node we are leaving. |
149 (or (null filename) | 188 (or (null filename) |
150 (equal Info-current-file filename) | 189 (equal Info-current-file filename) |
151 (let ((buffer-read-only nil)) | 190 (let ((buffer-read-only nil)) |
152 (setq Info-current-file nil | 191 (setq Info-current-file nil |
153 Info-current-subfile nil | 192 Info-current-subfile nil |
193 Info-index-alternatives nil | |
154 buffer-file-name nil) | 194 buffer-file-name nil) |
155 (erase-buffer) | 195 (erase-buffer) |
156 (if (eq filename t) | 196 (if (eq filename t) |
157 (Info-insert-dir) | 197 (Info-insert-dir) |
158 (insert-file-contents filename t) | 198 (info-insert-file-contents filename t) |
159 (setq default-directory (file-name-directory filename))) | 199 (setq default-directory (file-name-directory filename))) |
160 (set-buffer-modified-p nil) | 200 (set-buffer-modified-p nil) |
161 ;; See whether file has a tag table. Record the location if yes. | 201 ;; See whether file has a tag table. Record the location if yes. |
162 (set-marker Info-tag-table-marker nil) | 202 (set-marker Info-tag-table-marker nil) |
163 (goto-char (point-max)) | 203 (goto-char (point-max)) |
379 (or (equal Info-current-subfile lastfilename) | 419 (or (equal Info-current-subfile lastfilename) |
380 (let ((buffer-read-only nil)) | 420 (let ((buffer-read-only nil)) |
381 (setq buffer-file-name nil) | 421 (setq buffer-file-name nil) |
382 (widen) | 422 (widen) |
383 (erase-buffer) | 423 (erase-buffer) |
384 (insert-file-contents lastfilename) | 424 (info-insert-file-contents lastfilename) |
385 (set-buffer-modified-p nil) | 425 (set-buffer-modified-p nil) |
386 (setq Info-current-subfile lastfilename))) | 426 (setq Info-current-subfile lastfilename))) |
387 (goto-char (point-min)) | 427 (goto-char (point-min)) |
388 (search-forward "\n\^_") | 428 (search-forward "\n\^_") |
389 (+ (- nodepos lastfilepos) (point)))) | 429 (+ (- nodepos lastfilepos) (point)))) |
868 (if (pos-visible-in-window-p (point-min)) | 908 (if (pos-visible-in-window-p (point-min)) |
869 (Info-last-preorder) | 909 (Info-last-preorder) |
870 (scroll-down)) | 910 (scroll-down)) |
871 ) | 911 ) |
872 | 912 |
913 (defun Info-index (topic) | |
914 "Look up a string in the index for this file. | |
915 The index is defined as the first node in the top-level menu whose | |
916 name contains the word \"Index\", plus any immediately following | |
917 nodes whose names also contain the word \"Index\". | |
918 If there are no exact matches to the specified topic, this chooses | |
919 the first match which is a case-insensitive substring of a topic. | |
920 Use the `,' command to see the other matches. | |
921 Give a blank topic name to go to the Index node itself." | |
922 (interactive "sIndex topic: ") | |
923 (let ((orignode Info-current-node) | |
924 (rnode nil) | |
925 (pattern (format "\n\\* \\([^\n:]*%s[^\n:]*\\):[ \t]*\\([^.\n]*\\)\\.[ t]*\\([0-9]*\\)" | |
926 (regexp-quote topic))) | |
927 node) | |
928 (Info-goto-node "Top") | |
929 (or (search-forward "\n* menu:" nil t) | |
930 (error "No index")) | |
931 (or (re-search-forward "\n\\* \\(.*\\<Index\\>\\)" nil t) | |
932 (error "No index")) | |
933 (goto-char (match-beginning 1)) | |
934 (let ((Info-keeping-history nil)) | |
935 (Info-goto-node (Info-extract-menu-node-name))) | |
936 (or (equal topic "") | |
937 (let ((matches nil) | |
938 (exact nil) | |
939 (Info-keeping-history nil) | |
940 found) | |
941 (while | |
942 (progn | |
943 (goto-char (point-min)) | |
944 (while (re-search-forward pattern nil t) | |
945 (setq matches | |
946 (cons (list (buffer-substring (match-beginning 1) | |
947 (match-end 1)) | |
948 (buffer-substring (match-beginning 2) | |
949 (match-end 2)) | |
950 Info-current-node | |
951 (string-to-int (concat "0" | |
952 (buffer-substring | |
953 (match-beginning 3) | |
954 (match-end 3))))) | |
955 matches))) | |
956 (and (setq node (Info-extract-pointer "next" t)) | |
957 (string-match "\\<Index\\>" node))) | |
958 (Info-goto-node node)) | |
959 (or matches | |
960 (progn | |
961 (Info-last) | |
962 (error "No \"%s\" in index" topic))) | |
963 ;; Here it is a feature that assoc is case-sensitive. | |
964 (while (setq found (assoc topic matches)) | |
965 (setq exact (cons found exact) | |
966 matches (delq found matches))) | |
967 (setq Info-index-alternatives (nconc exact (nreverse matches))) | |
968 (Info-index-next 0))))) | |
969 | |
970 (defun Info-index-next (num) | |
971 "Go to the next matching index item from the last `i' command." | |
972 (interactive "p") | |
973 (or Info-index-alternatives | |
974 (error "No previous `i' command in this file")) | |
975 (while (< num 0) | |
976 (setq num (+ num (length Info-index-alternatives)))) | |
977 (while (> num 0) | |
978 (setq Info-index-alternatives | |
979 (nconc (cdr Info-index-alternatives) | |
980 (list (car Info-index-alternatives))) | |
981 num (1- num))) | |
982 (Info-goto-node (nth 1 (car Info-index-alternatives))) | |
983 (if (> (nth 3 (car Info-index-alternatives)) 0) | |
984 (forward-line (nth 3 (car Info-index-alternatives))) | |
985 (forward-line 3) ; don't search in headers | |
986 (let ((name (car (car Info-index-alternatives)))) | |
987 (if (or (re-search-forward (format | |
988 "\\(Function\\|Command\\): %s\\( \\|$\\)" | |
989 (regexp-quote name)) nil t) | |
990 (search-forward (format "`%s'" name) nil t) | |
991 (and (string-match "\\`.*\\( (.*)\\)\\'" name) | |
992 (search-forward | |
993 (format "`%s'" (substring name 0 (match-beginning 1))) | |
994 nil t)) | |
995 (search-forward name nil t)) | |
996 (beginning-of-line) | |
997 (goto-char (point-min))))) | |
998 (message "Found \"%s\" in %s. %s" | |
999 (car (car Info-index-alternatives)) | |
1000 (nth 2 (car Info-index-alternatives)) | |
1001 (if (cdr Info-index-alternatives) | |
1002 "(Press `,' for more)" | |
1003 "(Only match)"))) | |
1004 | |
873 (defun Info-undefined () | 1005 (defun Info-undefined () |
874 "Make command be undefined in Info." | 1006 "Make command be undefined in Info." |
875 (interactive) | 1007 (interactive) |
876 (ding)) | 1008 (ding)) |
877 | 1009 |
989 (define-key Info-mode-map "d" 'Info-directory) | 1121 (define-key Info-mode-map "d" 'Info-directory) |
990 (define-key Info-mode-map "e" 'Info-edit) | 1122 (define-key Info-mode-map "e" 'Info-edit) |
991 (define-key Info-mode-map "f" 'Info-follow-reference) | 1123 (define-key Info-mode-map "f" 'Info-follow-reference) |
992 (define-key Info-mode-map "g" 'Info-goto-node) | 1124 (define-key Info-mode-map "g" 'Info-goto-node) |
993 (define-key Info-mode-map "h" 'Info-help) | 1125 (define-key Info-mode-map "h" 'Info-help) |
1126 (define-key Info-mode-map "i" 'Info-index) | |
994 (define-key Info-mode-map "l" 'Info-last) | 1127 (define-key Info-mode-map "l" 'Info-last) |
995 (define-key Info-mode-map "m" 'Info-menu) | 1128 (define-key Info-mode-map "m" 'Info-menu) |
996 (define-key Info-mode-map "n" 'Info-next) | 1129 (define-key Info-mode-map "n" 'Info-next) |
997 (define-key Info-mode-map "p" 'Info-prev) | 1130 (define-key Info-mode-map "p" 'Info-prev) |
998 (define-key Info-mode-map "q" 'Info-exit) | 1131 (define-key Info-mode-map "q" 'Info-exit) |
999 (define-key Info-mode-map "s" 'Info-search) | 1132 (define-key Info-mode-map "s" 'Info-search) |
1133 (define-key Info-mode-map "t" 'Info-top) | |
1000 (define-key Info-mode-map "u" 'Info-up) | 1134 (define-key Info-mode-map "u" 'Info-up) |
1135 (define-key Info-mode-map "," 'Info-index-next) | |
1001 (define-key Info-mode-map "\177" 'Info-scroll-down) | 1136 (define-key Info-mode-map "\177" 'Info-scroll-down) |
1002 (define-key Info-mode-map [mouse-3] 'Info-follow-nearest-node) | 1137 (define-key Info-mode-map [mouse-3] 'Info-follow-nearest-node) |
1003 ) | 1138 ) |
1004 | 1139 |
1005 ;; Info mode is suitable only for specially formatted data. | 1140 ;; Info mode is suitable only for specially formatted data. |
1021 \\[Info-menu] Pick menu item specified by name (or abbreviation). | 1156 \\[Info-menu] Pick menu item specified by name (or abbreviation). |
1022 Picking a menu item causes another node to be selected. | 1157 Picking a menu item causes another node to be selected. |
1023 \\[Info-directory] Go to the Info directory node. | 1158 \\[Info-directory] Go to the Info directory node. |
1024 \\[Info-follow-reference] Follow a cross reference. Reads name of reference. | 1159 \\[Info-follow-reference] Follow a cross reference. Reads name of reference. |
1025 \\[Info-last] Move to the last node you were at. | 1160 \\[Info-last] Move to the last node you were at. |
1161 \\[Info-index] Look up a topic in this file's Index and move to that node. | |
1162 \\[Info-index-next] (comma) Move to the next match from a previous `i' command. | |
1026 | 1163 |
1027 Moving within a node: | 1164 Moving within a node: |
1028 \\[scroll-up] Normally, scroll forward a full screen. If the end of the buffer is | 1165 \\[scroll-up] Normally, scroll forward a full screen. If the end of the buffer is |
1029 already visible, try to go to the next menu entry, or up if there is none. | 1166 already visible, try to go to the next menu entry, or up if there is none. |
1030 \\[scroll-down] Normally, scroll backward. If the beginning of the buffer is | 1167 \\[scroll-down] Normally, scroll backward. If the beginning of the buffer is |
1054 (make-local-variable 'Info-current-file) | 1191 (make-local-variable 'Info-current-file) |
1055 (make-local-variable 'Info-current-subfile) | 1192 (make-local-variable 'Info-current-subfile) |
1056 (make-local-variable 'Info-current-node) | 1193 (make-local-variable 'Info-current-node) |
1057 (make-local-variable 'Info-tag-table-marker) | 1194 (make-local-variable 'Info-tag-table-marker) |
1058 (make-local-variable 'Info-history) | 1195 (make-local-variable 'Info-history) |
1196 (make-local-variable 'Info-index-alternatives) | |
1059 (Info-set-mode-line) | 1197 (Info-set-mode-line) |
1060 (run-hooks 'Info-mode-hook)) | 1198 (run-hooks 'Info-mode-hook)) |
1061 | 1199 |
1062 (defvar Info-edit-map nil | 1200 (defvar Info-edit-map nil |
1063 "Local keymap used within `e' command of Info.") | 1201 "Local keymap used within `e' command of Info.") |