1 |
;;; info.el --- info package for Emacs |
;;; info.el --- info package for Emacs |
2 |
|
|
3 |
;; Copyright (C) 1985, 86, 92, 93, 94, 95, 96, 97, 98, 99, 2000, 2001 |
;; Copyright (C) 1985, 86, 92, 93, 94, 95, 96, 97, 98, 99, 2000, 2001, |
4 |
|
;; 2002, 2003 |
5 |
;; Free Software Foundation, Inc. |
;; Free Software Foundation, Inc. |
6 |
|
|
7 |
;; Maintainer: FSF |
;; Maintainer: FSF |
27 |
;;; Commentary: |
;;; Commentary: |
28 |
|
|
29 |
;; Note that nowadays we expect info files to be made using makeinfo. |
;; Note that nowadays we expect info files to be made using makeinfo. |
30 |
|
;; In particular we make these assumptions: |
31 |
|
;; - a menu item MAY contain colons but not colon-space ": " |
32 |
|
;; - a menu item ending with ": " (but not ":: ") is an index entry |
33 |
|
;; - a node name MAY NOT contain a colon |
34 |
|
;; This distinction is to support indexing of computer programming |
35 |
|
;; language terms that may contain ":" but not ": ". |
36 |
|
|
37 |
;;; Code: |
;;; Code: |
38 |
|
|
72 |
(defface info-menu-5 |
(defface info-menu-5 |
73 |
'((((class color)) (:foreground "red1")) |
'((((class color)) (:foreground "red1")) |
74 |
(t (:underline t))) |
(t (:underline t))) |
75 |
"Face for the fifth and nineth `*' in an Info menu." |
"Face for every third `*' in an Info menu." |
76 |
:group 'info) |
:group 'info) |
77 |
|
|
78 |
(defface info-xref |
(defface info-xref |
83 |
:group 'info) |
:group 'info) |
84 |
|
|
85 |
(defcustom Info-fontify-maximum-menu-size 100000 |
(defcustom Info-fontify-maximum-menu-size 100000 |
86 |
"*Maximum size of menu to fontify if `Info-fontify' is non-nil." |
"*Maximum size of menu to fontify if `font-lock-mode' is non-nil." |
87 |
:type 'integer |
:type 'integer |
88 |
:group 'info) |
:group 'info) |
89 |
|
|
90 |
(defcustom Info-use-header-line t |
(defcustom Info-use-header-line t |
91 |
"*Non-nil means to put the beginning-of-node links in an emacs header-line. |
"*Non-nil means to put the beginning-of-node links in an Emacs header-line. |
92 |
A header-line does not scroll with the rest of the buffer." |
A header-line does not scroll with the rest of the buffer." |
93 |
:type 'boolean |
:type 'boolean |
94 |
:group 'info) |
:group 'info) |
105 |
|
|
106 |
(defvar Info-directory-list nil |
(defvar Info-directory-list nil |
107 |
"List of directories to search for Info documentation files. |
"List of directories to search for Info documentation files. |
108 |
nil means not yet initialized. In this case, Info uses the environment |
If nil, meaning not yet initialized, Info uses the environment |
109 |
variable INFOPATH to initialize it, or `Info-default-directory-list' |
variable INFOPATH to initialize it, or `Info-default-directory-list' |
110 |
if there is no INFOPATH variable in the environment. |
if there is no INFOPATH variable in the environment. |
111 |
|
|
134 |
|
|
135 |
(defcustom Info-additional-directory-list nil |
(defcustom Info-additional-directory-list nil |
136 |
"List of additional directories to search for Info documentation files. |
"List of additional directories to search for Info documentation files. |
137 |
These directories are searched after those in `Info-directory-list', and |
These directories are searched after those in `Info-directory-list'." |
|
they are not searched for merging the `dir' file." |
|
138 |
:type '(repeat directory) |
:type '(repeat directory) |
139 |
:group 'info) |
:group 'info) |
140 |
|
|
151 |
:type 'boolean |
:type 'boolean |
152 |
:group 'info) |
:group 'info) |
153 |
|
|
154 |
|
(defcustom Info-hide-note-references t |
155 |
|
"*If non-nil, hide the tag and section reference in *note and * menu items. |
156 |
|
Also replaces the \"*note\" text with \"see\". |
157 |
|
If value is non-nil but not t, the reference section is still shown." |
158 |
|
:version "21.4" |
159 |
|
:type '(choice (const :tag "No reformatting" nil) |
160 |
|
(const :tag "Replace tag and hide reference" t) |
161 |
|
(other :tag "Replace only tag" tag)) |
162 |
|
:group 'info) |
163 |
|
|
164 |
(defcustom Info-mode-hook '(turn-on-font-lock) |
(defcustom Info-mode-hook '(turn-on-font-lock) |
165 |
"Hooks run when `info-mode' is called." |
"Hooks run when `info-mode' is called." |
166 |
:type 'hook |
:type 'hook |
281 |
"Insert the contents of an info file in the current buffer. |
"Insert the contents of an info file in the current buffer. |
282 |
Do the right thing if the file has been compressed or zipped." |
Do the right thing if the file has been compressed or zipped." |
283 |
(let* ((tail Info-suffix-list) |
(let* ((tail Info-suffix-list) |
284 |
(lfn (or (not (fboundp 'msdos-long-file-names)) |
(lfn (if (fboundp 'msdos-long-file-names) |
285 |
(msdos-long-file-names))) |
(msdos-long-file-names) |
286 |
|
t)) |
287 |
(check-short (and (fboundp 'msdos-long-file-names) |
(check-short (and (fboundp 'msdos-long-file-names) |
288 |
lfn)) |
lfn)) |
289 |
fullname decoder done) |
fullname decoder done) |
423 |
(Info-directory)))) |
(Info-directory)))) |
424 |
|
|
425 |
;;;###autoload |
;;;###autoload |
426 |
|
(defun info-emacs-manual () |
427 |
|
"Display the Emacs manual in Info mode." |
428 |
|
(interactive) |
429 |
|
(info "emacs")) |
430 |
|
|
431 |
|
;;;###autoload |
432 |
(defun info-standalone () |
(defun info-standalone () |
433 |
"Run Emacs as a standalone Info reader. |
"Run Emacs as a standalone Info reader. |
434 |
Usage: emacs -f info-standalone [filename] |
Usage: emacs -f info-standalone [filename] |
497 |
(expand-file-name (downcase filename) (car dirs))) |
(expand-file-name (downcase filename) (car dirs))) |
498 |
;; Try several variants of specified name. |
;; Try several variants of specified name. |
499 |
(let ((suffix-list Info-suffix-list) |
(let ((suffix-list Info-suffix-list) |
500 |
(lfn (or (not (fboundp 'msdos-long-file-names)) |
(lfn (if (fboundp 'msdos-long-file-names) |
501 |
(msdos-long-file-names)))) |
(msdos-long-file-names) |
502 |
|
t))) |
503 |
(while (and suffix-list (not found)) |
(while (and suffix-list (not found)) |
504 |
(cond ((info-file-exists-p |
(cond ((info-file-exists-p |
505 |
(info-insert-file-contents-1 |
(info-insert-file-contents-1 |
543 |
(set (make-local-variable 'Info-current-file) t) |
(set (make-local-variable 'Info-current-file) t) |
544 |
(Info-find-node-2 nil nodename)) |
(Info-find-node-2 nil nodename)) |
545 |
|
|
546 |
|
;; It's perhaps a bit nasty to kill the *info* buffer to force a re-read, |
547 |
|
;; but at least it keeps this routine (which is only for the benefit of |
548 |
|
;; makeinfo-buffer) out of the way of normal operations. |
549 |
|
;; |
550 |
|
(defun Info-revert-find-node (filename nodename) |
551 |
|
"Go to an info node FILENAME and NODENAME, re-reading disk contents. |
552 |
|
When *info* is already displaying FILENAME and NODENAME, the window position |
553 |
|
is preserved, if possible." |
554 |
|
(pop-to-buffer "*info*") |
555 |
|
(let ((old-filename Info-current-file) |
556 |
|
(old-nodename Info-current-node) |
557 |
|
(pcolumn (current-column)) |
558 |
|
(pline (count-lines (point-min) (line-beginning-position))) |
559 |
|
(wline (count-lines (point-min) (window-start))) |
560 |
|
(old-history Info-history) |
561 |
|
(new-history (and Info-current-file |
562 |
|
(list Info-current-file Info-current-node (point))))) |
563 |
|
(kill-buffer (current-buffer)) |
564 |
|
(Info-find-node filename nodename) |
565 |
|
(setq Info-history old-history) |
566 |
|
(if (and (equal old-filename Info-current-file) |
567 |
|
(equal old-nodename Info-current-node)) |
568 |
|
(progn |
569 |
|
;; note goto-line is no good, we want to measure from point-min |
570 |
|
(beginning-of-buffer) |
571 |
|
(forward-line wline) |
572 |
|
(set-window-start (selected-window) (point)) |
573 |
|
(beginning-of-buffer) |
574 |
|
(forward-line pline) |
575 |
|
(move-to-column pcolumn)) |
576 |
|
;; only add to the history when coming from a different file+node |
577 |
|
(if new-history |
578 |
|
(setq Info-history (cons new-history Info-history)))))) |
579 |
|
|
580 |
(defun Info-find-in-tag-table-1 (marker regexp case-fold) |
(defun Info-find-in-tag-table-1 (marker regexp case-fold) |
581 |
"Find a node in a tag table. |
"Find a node in a tag table. |
582 |
MARKER specifies the buffer and position to start searching at. |
MARKER specifies the buffer and position to start searching at. |
592 |
(save-excursion |
(save-excursion |
593 |
(set-buffer (marker-buffer marker)) |
(set-buffer (marker-buffer marker)) |
594 |
(goto-char marker) |
(goto-char marker) |
595 |
|
|
596 |
;; Search tag table |
;; Search tag table |
597 |
(beginning-of-line) |
(beginning-of-line) |
598 |
(when (re-search-forward regexp nil t) |
(when (re-search-forward regexp nil t) |
636 |
(beginning-of-line) |
(beginning-of-line) |
637 |
(setq found (point))))) |
(setq found (point))))) |
638 |
found))) |
found))) |
639 |
|
|
640 |
(defun Info-find-node-in-buffer (regexp) |
(defun Info-find-node-in-buffer (regexp) |
641 |
"Find a node or anchor in the current buffer. |
"Find a node or anchor in the current buffer. |
642 |
REGEXP is a regular expression matching nodes or references. Its first |
REGEXP is a regular expression matching nodes or references. Its first |
646 |
a case-insensitive match is tried." |
a case-insensitive match is tried." |
647 |
(or (Info-find-node-in-buffer-1 regexp nil) |
(or (Info-find-node-in-buffer-1 regexp nil) |
648 |
(Info-find-node-in-buffer-1 regexp t))) |
(Info-find-node-in-buffer-1 regexp t))) |
649 |
|
|
650 |
(defun Info-find-node-2 (filename nodename &optional no-going-back) |
(defun Info-find-node-2 (filename nodename &optional no-going-back) |
651 |
(buffer-disable-undo (current-buffer)) |
(buffer-disable-undo (current-buffer)) |
652 |
(or (eq major-mode 'Info-mode) |
(or (eq major-mode 'Info-mode) |
729 |
(nodepos nil)) |
(nodepos nil)) |
730 |
|
|
731 |
(catch 'foo |
(catch 'foo |
732 |
|
|
733 |
;; First, search a tag table, if any |
;; First, search a tag table, if any |
734 |
(when (marker-position Info-tag-table-marker) |
(when (marker-position Info-tag-table-marker) |
735 |
(let* ((m Info-tag-table-marker) |
(let* ((m Info-tag-table-marker) |
736 |
(found (Info-find-in-tag-table m regexp))) |
(found (Info-find-in-tag-table m regexp))) |
737 |
|
|
738 |
(when found |
(when found |
739 |
;; FOUND is (ANCHOR POS MODE). |
;; FOUND is (ANCHOR POS MODE). |
740 |
(setq guesspos (nth 1 found)) |
(setq guesspos (nth 1 found)) |
741 |
|
|
742 |
;; If this is an indirect file, determine which |
;; If this is an indirect file, determine which |
743 |
;; file really holds this node and read it in. |
;; file really holds this node and read it in. |
744 |
(unless (eq (nth 2 found) 'Info-mode) |
(unless (eq (nth 2 found) 'Info-mode) |
755 |
;; Else we may have a node, which we search for: |
;; Else we may have a node, which we search for: |
756 |
(goto-char (max (point-min) |
(goto-char (max (point-min) |
757 |
(- (byte-to-position guesspos) 1000))) |
(- (byte-to-position guesspos) 1000))) |
758 |
|
|
759 |
;; Now search from our advised position (or from beg of |
;; Now search from our advised position (or from beg of |
760 |
;; buffer) to find the actual node. First, check |
;; buffer) to find the actual node. First, check |
761 |
;; whether the node is right where we are, in case the |
;; whether the node is right where we are, in case the |
814 |
(insert Info-dir-contents) |
(insert Info-dir-contents) |
815 |
(goto-char (point-min))) |
(goto-char (point-min))) |
816 |
(let ((dirs (if Info-additional-directory-list |
(let ((dirs (if Info-additional-directory-list |
817 |
(append Info-directory-list |
(append Info-directory-list |
818 |
Info-additional-directory-list) |
Info-additional-directory-list) |
819 |
Info-directory-list)) |
Info-directory-list)) |
820 |
|
(dir-file-attrs nil) |
821 |
;; Bind this in case the user sets it to nil. |
;; Bind this in case the user sets it to nil. |
822 |
(case-fold-search t) |
(case-fold-search t) |
823 |
;; This is set non-nil if we find a problem in some input files. |
;; This is set non-nil if we find a problem in some input files. |
824 |
problems |
problems |
825 |
buffers buffer others nodes dirs-done) |
buffers buffer others nodes dirs-done) |
826 |
|
|
|
(setq Info-dir-file-attributes nil) |
|
|
|
|
827 |
;; Search the directory list for the directory file. |
;; Search the directory list for the directory file. |
828 |
(while dirs |
(while dirs |
829 |
(let ((truename (file-truename (expand-file-name (car dirs))))) |
(let ((truename (file-truename (expand-file-name (car dirs))))) |
854 |
(condition-case nil |
(condition-case nil |
855 |
(progn |
(progn |
856 |
(insert-file-contents file) |
(insert-file-contents file) |
857 |
(make-local-variable 'Info-dir-file-name) |
(set (make-local-variable 'Info-dir-file-name) |
858 |
(setq Info-dir-file-name file) |
file) |
859 |
(setq buffers (cons (current-buffer) buffers) |
(push (current-buffer) buffers) |
860 |
Info-dir-file-attributes |
(push (cons file attrs) dir-file-attrs)) |
|
(cons (cons file attrs) |
|
|
Info-dir-file-attributes))) |
|
861 |
(error (kill-buffer (current-buffer)))))))) |
(error (kill-buffer (current-buffer)))))))) |
862 |
(or (cdr dirs) (setq Info-dir-contents-directory |
(unless (cdr dirs) |
863 |
(file-name-as-directory (car dirs)))) |
(set (make-local-variable 'Info-dir-contents-directory) |
864 |
|
(file-name-as-directory (car dirs)))) |
865 |
(setq dirs (cdr dirs)))) |
(setq dirs (cdr dirs)))) |
866 |
|
|
867 |
(or buffers |
(or buffers |
868 |
(error "Can't find the Info directory node")) |
(error "Can't find the Info directory node")) |
869 |
|
|
870 |
;; Distinguish the dir file that comes with Emacs from all the |
;; Distinguish the dir file that comes with Emacs from all the |
871 |
;; others. Yes, that is really what this is supposed to do. |
;; others. Yes, that is really what this is supposed to do. |
872 |
;; The definition of `Info-directory-list' puts it first on that |
;; The definition of `Info-directory-list' puts it first on that |
880 |
(insert-buffer buffer) |
(insert-buffer buffer) |
881 |
|
|
882 |
;; Look at each of the other buffers one by one. |
;; Look at each of the other buffers one by one. |
883 |
(while others |
(dolist (other others) |
884 |
(let ((other (car others)) |
(let (this-buffer-nodes) |
|
;; Bind this in case the user sets it to nil. |
|
|
(case-fold-search t) |
|
|
this-buffer-nodes) |
|
885 |
;; In each, find all the menus. |
;; In each, find all the menus. |
886 |
(save-excursion |
(with-current-buffer other |
|
(set-buffer other) |
|
887 |
(goto-char (point-min)) |
(goto-char (point-min)) |
888 |
;; Find each menu, and add an elt to NODES for it. |
;; Find each menu, and add an elt to NODES for it. |
889 |
(while (re-search-forward "^\\* Menu:" nil t) |
(while (re-search-forward "^\\* Menu:" nil t) |
890 |
(let (beg nodename end) |
(while (and (zerop (forward-line 1)) (eolp))) |
891 |
(forward-line 1) |
(let ((beg (point)) |
892 |
(while (and (eolp) (not (eobp))) |
nodename end) |
893 |
(forward-line 1)) |
(re-search-backward "^\^_") |
|
(setq beg (point)) |
|
|
(or (search-backward "\n\^_" nil 'move) |
|
|
(looking-at "\^_") |
|
|
(signal 'search-failed (list "\n\^_"))) |
|
894 |
(search-forward "Node: ") |
(search-forward "Node: ") |
895 |
(setq nodename (Info-following-node-name)) |
(setq nodename (Info-following-node-name)) |
896 |
(search-forward "\n\^_" nil 'move) |
(search-forward "\n\^_" nil 'move) |
897 |
(beginning-of-line) |
(beginning-of-line) |
898 |
(setq end (point)) |
(setq end (point)) |
899 |
(setq this-buffer-nodes |
(push (list nodename other beg end) this-buffer-nodes))) |
|
(cons (list nodename other beg end) |
|
|
this-buffer-nodes)))) |
|
900 |
(if (assoc-ignore-case "top" this-buffer-nodes) |
(if (assoc-ignore-case "top" this-buffer-nodes) |
901 |
(setq nodes (nconc this-buffer-nodes nodes)) |
(setq nodes (nconc this-buffer-nodes nodes)) |
902 |
(setq problems t) |
(setq problems t) |
903 |
(message "No `top' node in %s" Info-dir-file-name)))) |
(message "No `top' node in %s" Info-dir-file-name))))) |
|
(setq others (cdr others))) |
|
904 |
;; Add to the main menu a menu item for each other node. |
;; Add to the main menu a menu item for each other node. |
905 |
(let ((case-fold-search t) |
(re-search-forward "^\\* Menu:") |
|
(re-search-forward "^\\* Menu:"))) |
|
906 |
(forward-line 1) |
(forward-line 1) |
907 |
(let ((menu-items '("top")) |
(let ((menu-items '("top")) |
|
(nodes nodes) |
|
|
(case-fold-search t) |
|
908 |
(end (save-excursion (search-forward "\^_" nil t) (point)))) |
(end (save-excursion (search-forward "\^_" nil t) (point)))) |
909 |
(while nodes |
(dolist (node nodes) |
910 |
(let ((nodename (car (car nodes)))) |
(let ((nodename (car node))) |
911 |
(save-excursion |
(save-excursion |
912 |
(or (member (downcase nodename) menu-items) |
(or (member (downcase nodename) menu-items) |
913 |
(re-search-forward (concat "^\\* +" |
(re-search-forward (concat "^\\* +" |
916 |
end t) |
end t) |
917 |
(progn |
(progn |
918 |
(insert "* " nodename "::" "\n") |
(insert "* " nodename "::" "\n") |
919 |
(setq menu-items (cons nodename menu-items)))))) |
(push nodename menu-items))))))) |
|
(setq nodes (cdr nodes)))) |
|
920 |
;; Now take each node of each of the other buffers |
;; Now take each node of each of the other buffers |
921 |
;; and merge it into the main buffer. |
;; and merge it into the main buffer. |
922 |
(while nodes |
(dolist (node nodes) |
923 |
(let ((case-fold-search t) |
(let ((case-fold-search t) |
924 |
(nodename (car (car nodes)))) |
(nodename (car node))) |
925 |
(goto-char (point-min)) |
(goto-char (point-min)) |
926 |
;; Find the like-named node in the main buffer. |
;; Find the like-named node in the main buffer. |
927 |
(if (re-search-forward (concat "^\^_.*\n.*Node: " |
(if (re-search-forward (concat "^\^_.*\n.*Node: " |
937 |
(insert "\^_\nFile: dir\tNode: " nodename "\n\n* Menu:\n\n")) |
(insert "\^_\nFile: dir\tNode: " nodename "\n\n* Menu:\n\n")) |
938 |
;; Merge the text from the other buffer's menu |
;; Merge the text from the other buffer's menu |
939 |
;; into the menu in the like-named node in the main buffer. |
;; into the menu in the like-named node in the main buffer. |
940 |
(apply 'insert-buffer-substring (cdr (car nodes)))) |
(apply 'insert-buffer-substring (cdr node)))) |
941 |
(setq nodes (cdr nodes))) |
(Info-dir-remove-duplicates) |
942 |
;; Kill all the buffers we just made. |
;; Kill all the buffers we just made. |
943 |
(while buffers |
(mapc 'kill-buffer buffers) |
|
(kill-buffer (car buffers)) |
|
|
(setq buffers (cdr buffers))) |
|
944 |
(goto-char (point-min)) |
(goto-char (point-min)) |
945 |
(if problems |
(if problems |
946 |
(message "Composing main Info directory...problems encountered, see `*Messages*'") |
(message "Composing main Info directory...problems encountered, see `*Messages*'") |
947 |
(message "Composing main Info directory...done"))) |
(message "Composing main Info directory...done")) |
948 |
(setq Info-dir-contents (buffer-string))) |
(set (make-local-variable 'Info-dir-contents) (buffer-string)) |
949 |
|
(set (make-local-variable 'Info-dir-file-attributes) dir-file-attrs))) |
950 |
(setq default-directory Info-dir-contents-directory)) |
(setq default-directory Info-dir-contents-directory)) |
951 |
|
|
952 |
|
(defvar Info-streamline-headings |
953 |
|
'(("Emacs" . "Emacs") |
954 |
|
("Programming" . "Programming") |
955 |
|
("Libraries" . "Libraries") |
956 |
|
("World Wide Web\\|Net Utilities" . "Net Utilities")) |
957 |
|
"List of elements (RE . NAME) to merge headings matching RE to NAME.") |
958 |
|
|
959 |
|
(defun Info-dir-remove-duplicates () |
960 |
|
(let (limit) |
961 |
|
(goto-char (point-min)) |
962 |
|
;; Remove duplicate headings in the same menu. |
963 |
|
(while (search-forward "\n* Menu:" nil t) |
964 |
|
(setq limit (save-excursion (search-forward "\n" nil t))) |
965 |
|
;; Look for the next heading to unify. |
966 |
|
(while (re-search-forward "^\\(\\w.*\\)\n\\*" limit t) |
967 |
|
(let ((name (match-string 1)) |
968 |
|
(start (match-beginning 0)) |
969 |
|
(entries nil) re) |
970 |
|
;; Check whether this heading should be streamlined. |
971 |
|
(save-match-data |
972 |
|
(dolist (x Info-streamline-headings) |
973 |
|
(when (string-match (car x) name) |
974 |
|
(setq name (cdr x)) |
975 |
|
(setq re (car x))))) |
976 |
|
(if re (replace-match name t t nil 1)) |
977 |
|
(goto-char (if (re-search-forward "^[^* \n\t]" limit t) |
978 |
|
(match-beginning 0) |
979 |
|
(or limit (point-max)))) |
980 |
|
;; Look for other headings of the same category and merge them. |
981 |
|
(save-excursion |
982 |
|
(while (re-search-forward "^\\(\\w.*\\)\n\\*" limit t) |
983 |
|
(when (if re (save-match-data (string-match re (match-string 1))) |
984 |
|
(equal name (match-string 1))) |
985 |
|
(forward-line 0) |
986 |
|
;; Delete redundant heading. |
987 |
|
(delete-region (match-beginning 0) (point)) |
988 |
|
;; Push the entries onto `text'. |
989 |
|
(push |
990 |
|
(delete-and-extract-region |
991 |
|
(point) |
992 |
|
(if (re-search-forward "^[^* \n\t]" nil t) |
993 |
|
(match-beginning 0) |
994 |
|
(or limit (point-max)))) entries)))) |
995 |
|
;; Insert the entries just found. |
996 |
|
(while (= (line-beginning-position 0) (1- (point))) |
997 |
|
(backward-char)) |
998 |
|
(dolist (entry (nreverse entries)) |
999 |
|
(insert entry) |
1000 |
|
(while (= (line-beginning-position 0) (1- (point))) |
1001 |
|
(delete-region (1- (point)) (point)))) |
1002 |
|
|
1003 |
|
;; Now remove duplicate entries under the same heading. |
1004 |
|
(let ((seen nil) |
1005 |
|
(limit (point))) |
1006 |
|
(goto-char start) |
1007 |
|
(while (re-search-forward "^* \\([^:\n]+:\\(:\\|[^.\n]+\\).\\)" |
1008 |
|
limit 'move) |
1009 |
|
(let ((x (match-string 1))) |
1010 |
|
(if (member-ignore-case x seen) |
1011 |
|
(delete-region (match-beginning 0) |
1012 |
|
(progn (re-search-forward "^[^ \t]" nil t) |
1013 |
|
(match-beginning 0))) |
1014 |
|
(push x seen)))))))))) |
1015 |
|
|
1016 |
;; Note that on entry to this function the current-buffer must be the |
;; Note that on entry to this function the current-buffer must be the |
1017 |
;; *info* buffer; not the info tags buffer. |
;; *info* buffer; not the info tags buffer. |
1018 |
(defun Info-read-subfile (nodepos) |
(defun Info-read-subfile (nodepos) |
1103 |
(point-max))) |
(point-max))) |
1104 |
(if Info-enable-active-nodes (eval active-expression)) |
(if Info-enable-active-nodes (eval active-expression)) |
1105 |
(Info-fontify-node) |
(Info-fontify-node) |
1106 |
(if Info-use-header-line |
(setq Info-header-line (get-text-property (point-min) 'header-line)) |
|
(Info-setup-header-line) |
|
|
(setq Info-header-line nil) |
|
|
(setq header-line-format nil)) ; so the header line isn't displayed |
|
1107 |
(run-hooks 'Info-selection-hook))))) |
(run-hooks 'Info-selection-hook))))) |
1108 |
|
|
1109 |
(defun Info-set-mode-line () |
(defun Info-set-mode-line () |
1118 |
") " |
") " |
1119 |
(or Info-current-node "")))))) |
(or Info-current-node "")))))) |
1120 |
|
|
|
;; Skip the node header and make it into a header-line. This function |
|
|
;; should be called when the node is already narrowed. |
|
|
(defun Info-setup-header-line () |
|
|
(goto-char (point-min)) |
|
|
(let* ((case-fold-search t) |
|
|
(header-end (save-excursion (forward-line 1) (1- (point)))) |
|
|
;; If we find neither Next: nor Prev: link, show the entire |
|
|
;; node header. Otherwise, don't show the File: and Node: |
|
|
;; parts, to avoid wasting precious space on information that |
|
|
;; is available in the mode line. |
|
|
(header-beg (if (re-search-forward |
|
|
"\\(next\\|prev[ious]*\\): " |
|
|
header-end t) |
|
|
(match-beginning 1) |
|
|
(point)))) |
|
|
(set (make-local-variable 'Info-header-line) |
|
|
(buffer-substring header-beg header-end)) |
|
|
(setq header-line-format 'Info-header-line) |
|
|
;;; It is useful to be able to copy the links line out of the buffer |
|
|
;;; with M-w. |
|
|
;;; (narrow-to-region (1+ header-end) (point-max)) |
|
|
)) |
|
|
|
|
1121 |
;; Go to an info node specified with a filename-and-nodename string |
;; Go to an info node specified with a filename-and-nodename string |
1122 |
;; of the sort that is found in pointers in nodes. |
;; of the sort that is found in pointers in nodes. |
1123 |
|
|
1282 |
(progn (search-forward "\n\^_") |
(progn (search-forward "\n\^_") |
1283 |
(1- (point)))) |
(1- (point)))) |
1284 |
(goto-char (point-min)) |
(goto-char (point-min)) |
1285 |
|
;; Find the subfile we just searched. |
1286 |
(search-forward (concat "\n" osubfile ": ")) |
(search-forward (concat "\n" osubfile ": ")) |
1287 |
(beginning-of-line) |
;; Skip that one. |
1288 |
|
(forward-line 1) |
1289 |
|
;; Make a list of all following subfiles. |
1290 |
|
;; Each elt has the form (VIRT-POSITION . SUBFILENAME). |
1291 |
(while (not (eobp)) |
(while (not (eobp)) |
1292 |
(re-search-forward "\\(^.*\\): [0-9]+$") |
(re-search-forward "\\(^.*\\): [0-9]+$") |
1293 |
(goto-char (+ (match-end 1) 2)) |
(goto-char (+ (match-end 1) 2)) |
1294 |
(setq list (cons (cons (read (current-buffer)) |
(setq list (cons (cons (+ (point-min) |
1295 |
|
(read (current-buffer))) |
1296 |
(match-string-no-properties 1)) |
(match-string-no-properties 1)) |
1297 |
list)) |
list)) |
1298 |
(goto-char (1+ (match-end 0)))) |
(goto-char (1+ (match-end 0)))) |
1299 |
(setq list (nreverse list) |
;; Put in forward order |
1300 |
current (car (car list)) |
(setq list (nreverse list)))) |
|
list (cdr list)))) |
|
1301 |
(while list |
(while list |
1302 |
(message "Searching subfile %s..." (cdr (car list))) |
(message "Searching subfile %s..." (cdr (car list))) |
1303 |
(Info-read-subfile (car (car list))) |
(Info-read-subfile (car (car list))) |
1330 |
(save-excursion |
(save-excursion |
1331 |
(save-restriction |
(save-restriction |
1332 |
(goto-char (point-min)) |
(goto-char (point-min)) |
|
;;; (when Info-header-line |
|
|
;;; ;; expose the header line in the buffer |
|
|
;;; (widen) |
|
|
;;; (forward-line -1)) |
|
1333 |
(let ((bound (point))) |
(let ((bound (point))) |
1334 |
(forward-line 1) |
(forward-line 1) |
1335 |
(cond ((re-search-backward (concat name ":") bound t) |
(cond ((re-search-backward (concat name ":") bound t) |
1486 |
(skip-chars-forward " \t\n") |
(skip-chars-forward " \t\n") |
1487 |
(let ((beg (point)) |
(let ((beg (point)) |
1488 |
str i) |
str i) |
1489 |
(skip-chars-forward "^:") |
(while (not (looking-at ":*[,.;() \t\n]")) |
1490 |
(forward-char 1) |
(skip-chars-forward "^:") |
1491 |
|
(forward-char 1)) |
1492 |
(setq str |
(setq str |
1493 |
(if (looking-at ":") |
(if (looking-at ":") |
1494 |
(buffer-substring-no-properties beg (1- (point))) |
(buffer-substring-no-properties beg (1- (point))) |
1527 |
(concat "\n\\* +" (regexp-quote string) ":") nil t) |
(concat "\n\\* +" (regexp-quote string) ":") nil t) |
1528 |
(let ((pattern (concat "\n\\* +\\(" |
(let ((pattern (concat "\n\\* +\\(" |
1529 |
(regexp-quote string) |
(regexp-quote string) |
1530 |
"[^:\t\n]*\\):")) |
"[^\t\n]*\\):")) |
1531 |
completions) |
completions) |
1532 |
;; Check the cache. |
;; Check the cache. |
1533 |
(if (and (equal (nth 0 Info-complete-cache) Info-current-file) |
(if (and (equal (nth 0 Info-complete-cache) Info-current-file) |
1553 |
(unless (equal Info-current-node orignode) |
(unless (equal Info-current-node orignode) |
1554 |
(Info-goto-node orignode)) |
(Info-goto-node orignode)) |
1555 |
;; Update the cache. |
;; Update the cache. |
1556 |
(setq Info-complete-cache |
(set (make-local-variable 'Info-complete-cache) |
1557 |
(list Info-current-file Info-current-node |
(list Info-current-file Info-current-node |
1558 |
Info-complete-next-re string completions))) |
Info-complete-next-re string completions))) |
1559 |
(if action |
(if action |
1560 |
(all-completions string completions predicate) |
(all-completions string completions predicate) |
1561 |
(try-completion string completions predicate))))))) |
(try-completion string completions predicate))))))) |
1585 |
(save-excursion |
(save-excursion |
1586 |
(goto-char p) |
(goto-char p) |
1587 |
(end-of-line) |
(end-of-line) |
1588 |
(if (re-search-backward "\n\\* +\\([^:\t\n]*\\):" beg t) |
(if (re-search-backward "\n\\* +\\([^\t\n]*\\):" beg t) |
1589 |
(setq default (match-string-no-properties 1)))))) |
(setq default (match-string-no-properties 1)))))) |
1590 |
(let ((item nil)) |
(let ((item nil)) |
1591 |
(while (null item) |
(while (null item) |
1683 |
(not (string-match "\\<index\\>" Info-current-node))) |
(not (string-match "\\<index\\>" Info-current-node))) |
1684 |
(Info-goto-node (Info-extract-menu-counting 1)) |
(Info-goto-node (Info-extract-menu-counting 1)) |
1685 |
t) |
t) |
1686 |
((save-excursion |
((save-excursion (search-backward "next:" nil t)) |
|
(save-restriction |
|
|
(let (limit) |
|
|
(when Info-header-line |
|
|
(goto-char (point-min)) |
|
|
(widen) |
|
|
(forward-line -1) |
|
|
(setq limit (point)) |
|
|
(forward-line 1)) |
|
|
(search-backward "next:" limit t)))) |
|
1687 |
(Info-next) |
(Info-next) |
1688 |
t) |
t) |
1689 |
((and (save-excursion |
((and (save-excursion (search-backward "up:" nil t)) |
|
(save-restriction |
|
|
(let (limit) |
|
|
(when Info-header-line |
|
|
(goto-char (point-min)) |
|
|
(widen) |
|
|
(forward-line -1) |
|
|
(setq limit (point)) |
|
|
(forward-line 1)) |
|
|
(search-backward "up:" limit t)))) |
|
1690 |
;; Use string-equal, not equal, to ignore text props. |
;; Use string-equal, not equal, to ignore text props. |
1691 |
(not (string-equal (downcase (Info-extract-pointer "up")) |
(not (string-equal (downcase (Info-extract-pointer "up")) |
1692 |
"top"))) |
"top"))) |
1732 |
(quit-window))) |
(quit-window))) |
1733 |
|
|
1734 |
(defun Info-next-menu-item () |
(defun Info-next-menu-item () |
1735 |
|
"Go to the node of the next menu item." |
1736 |
(interactive) |
(interactive) |
1737 |
;; Bind this in case the user sets it to nil. |
;; Bind this in case the user sets it to nil. |
1738 |
(let* ((case-fold-search t) |
(let* ((case-fold-search t) |
1746 |
(error "No more items in menu")))) |
(error "No more items in menu")))) |
1747 |
|
|
1748 |
(defun Info-last-menu-item () |
(defun Info-last-menu-item () |
1749 |
|
"Go to the node of the previous menu item." |
1750 |
(interactive) |
(interactive) |
1751 |
(save-excursion |
(save-excursion |
1752 |
(forward-line 1) |
(forward-line 1) |
1866 |
(search-forward "\n* Menu:" |
(search-forward "\n* Menu:" |
1867 |
current-point |
current-point |
1868 |
t))))) |
t))))) |
1869 |
(if (or virtual-end |
(if (or virtual-end |
1870 |
(pos-visible-in-window-p (point-min) nil t)) |
(pos-visible-in-window-p (point-min) nil t)) |
1871 |
(Info-last-preorder) |
(Info-last-preorder) |
1872 |
(scroll-down)))) |
(scroll-down)))) |
1934 |
(list |
(list |
1935 |
(let ((Info-complete-menu-buffer (clone-buffer)) |
(let ((Info-complete-menu-buffer (clone-buffer)) |
1936 |
(Info-complete-next-re "\\<Index\\>")) |
(Info-complete-next-re "\\<Index\\>")) |
1937 |
|
(if (equal Info-current-file "dir") |
1938 |
|
(error "The Info directory node has no index; use m to select a manual")) |
1939 |
(unwind-protect |
(unwind-protect |
1940 |
(with-current-buffer Info-complete-menu-buffer |
(with-current-buffer Info-complete-menu-buffer |
1941 |
(Info-goto-index) |
(Info-goto-index) |
1942 |
(completing-read "Index topic: " 'Info-complete-menu-item)) |
(completing-read "Index topic: " 'Info-complete-menu-item)) |
1943 |
(kill-buffer Info-complete-menu-buffer))))) |
(kill-buffer Info-complete-menu-buffer))))) |
1944 |
|
(if (equal Info-current-file "dir") |
1945 |
|
(error "The Info directory node has no index; use m to select a manual")) |
1946 |
(let ((orignode Info-current-node) |
(let ((orignode Info-current-node) |
1947 |
(rnode nil) |
(rnode nil) |
1948 |
(pattern (format "\n\\* +\\([^\n:]*%s[^\n:]*\\):[ \t]*\\([^.\n]*\\)\\.[ \t]*\\([0-9]*\\)" |
(pattern (format "\n\\* +\\([^\n]*%s[^\n]*\\):[ \t]+\\([^.\n]*\\)\\.[ \t]*\\([0-9]*\\)" |
1949 |
(regexp-quote topic))) |
(regexp-quote topic))) |
1950 |
node |
node |
1951 |
(case-fold-search t)) |
(case-fold-search t)) |
1966 |
(push (list (match-string-no-properties 1) |
(push (list (match-string-no-properties 1) |
1967 |
(match-string-no-properties 2) |
(match-string-no-properties 2) |
1968 |
Info-current-node |
Info-current-node |
1969 |
(string-to-int (concat "0" |
(string-to-number (concat "0" |
1970 |
(match-string 3)))) |
(match-string 3)))) |
1971 |
matches)) |
matches)) |
1972 |
(and (setq node (Info-extract-pointer "next" t)) |
(and (setq node (Info-extract-pointer "next" t)) |
1973 |
(string-match "\\<Index\\>" node))) |
(string-match "\\<Index\\>" node))) |
2005 |
(car (car Info-index-alternatives)) |
(car (car Info-index-alternatives)) |
2006 |
(nth 2 (car Info-index-alternatives)) |
(nth 2 (car Info-index-alternatives)) |
2007 |
(if (cdr Info-index-alternatives) |
(if (cdr Info-index-alternatives) |
2008 |
"(Press `,' for more)" |
"(`,' tries to find next)" |
2009 |
"(Only match)"))) |
"(Only match)"))) |
2010 |
|
|
2011 |
(defun Info-find-index-name (name) |
(defun Info-find-index-name (name) |
2014 |
(if (or (re-search-forward (format |
(if (or (re-search-forward (format |
2015 |
"[a-zA-Z]+: %s\\( \\|$\\)" |
"[a-zA-Z]+: %s\\( \\|$\\)" |
2016 |
(regexp-quote name)) nil t) |
(regexp-quote name)) nil t) |
2017 |
|
;; Find a function definition with a return type. |
2018 |
|
(re-search-forward (format |
2019 |
|
"[a-zA-Z]+: [a-zA-Z0-9_ *&]+ %s\\( \\|$\\)" |
2020 |
|
(regexp-quote name)) nil t) |
2021 |
(search-forward (format "`%s'" name) nil t) |
(search-forward (format "`%s'" name) nil t) |
2022 |
(and (string-match "\\`.*\\( (.*)\\)\\'" name) |
(and (string-match "\\`.*\\( (.*)\\)\\'" name) |
2023 |
(search-forward |
(search-forward |
2113 |
(Info-next-preorder))) |
(Info-next-preorder))) |
2114 |
|
|
2115 |
(defun Info-follow-nearest-node () |
(defun Info-follow-nearest-node () |
2116 |
"\\<Info-mode-map>Follow a node reference near point. |
"Follow a node reference near point. |
2117 |
Like \\[Info-menu], \\[Info-follow-reference], \\[Info-next], \\[Info-prev] or \\[Info-up] command, depending on where point is. |
If point is on a reference, follow that reference. Otherwise, |
2118 |
If no reference to follow, moves to the next node, or up if none." |
if point is in a menu item description, follow that menu item." |
2119 |
(interactive) |
(interactive) |
2120 |
(or (Info-try-follow-nearest-node) |
(or (Info-try-follow-nearest-node) |
2121 |
(Info-next-preorder))) |
(when (save-excursion |
2122 |
|
(search-backward "\n* menu:" nil t)) |
2123 |
|
(save-excursion |
2124 |
|
(beginning-of-line) |
2125 |
|
(while (not (or (bobp) (looking-at "[^ \t]\\|[ \t]*$"))) |
2126 |
|
(beginning-of-line 0)) |
2127 |
|
(when (looking-at "\\* +\\([^\t\n]*\\):") |
2128 |
|
(Info-goto-node |
2129 |
|
(Info-extract-menu-item (match-string-no-properties 1))) |
2130 |
|
t))) |
2131 |
|
(error "Point neither on reference nor in menu item description"))) |
2132 |
|
|
2133 |
;; Common subroutine. |
;; Common subroutine. |
2134 |
(defun Info-try-follow-nearest-node () |
(defun Info-try-follow-nearest-node () |
2138 |
((setq node (Info-get-token (point) "\\*note[ \n]" |
((setq node (Info-get-token (point) "\\*note[ \n]" |
2139 |
"\\*note[ \n]\\([^:]*\\):")) |
"\\*note[ \n]\\([^:]*\\):")) |
2140 |
(Info-follow-reference node)) |
(Info-follow-reference node)) |
2141 |
|
;; menu item: node name |
2142 |
((setq node (Info-get-token (point) "\\* +" "\\* +\\([^:]*\\)::")) |
((setq node (Info-get-token (point) "\\* +" "\\* +\\([^:]*\\)::")) |
2143 |
(Info-goto-node node)) |
(Info-goto-node node)) |
2144 |
((Info-get-token (point) "\\* +" "\\* +\\([^:]*\\):") |
;; menu item: index entry |
2145 |
|
((Info-get-token (point) "\\* +" "\\* +\\(.*\\): ") |
2146 |
(beginning-of-line) |
(beginning-of-line) |
2147 |
(forward-char 2) |
(forward-char 2) |
2148 |
(setq node (Info-extract-menu-node-name)) |
(setq node (Info-extract-menu-node-name)) |
2420 |
(setq local-abbrev-table text-mode-abbrev-table) |
(setq local-abbrev-table text-mode-abbrev-table) |
2421 |
(setq case-fold-search t) |
(setq case-fold-search t) |
2422 |
(setq buffer-read-only t) |
(setq buffer-read-only t) |
|
(set (make-local-variable 'font-lock-defaults) |
|
|
'(nil t nil nil nil (font-lock-core-only . t))) |
|
2423 |
(make-local-variable 'Info-current-file) |
(make-local-variable 'Info-current-file) |
2424 |
(make-local-variable 'Info-current-subfile) |
(make-local-variable 'Info-current-subfile) |
2425 |
(make-local-variable 'Info-current-node) |
(make-local-variable 'Info-current-node) |
2429 |
(setq Info-tag-table-buffer nil) |
(setq Info-tag-table-buffer nil) |
2430 |
(make-local-variable 'Info-history) |
(make-local-variable 'Info-history) |
2431 |
(make-local-variable 'Info-index-alternatives) |
(make-local-variable 'Info-index-alternatives) |
2432 |
|
(make-local-variable 'Info-header-line) |
2433 |
|
(setq header-line-format (if Info-use-header-line 'Info-header-line)) |
2434 |
(set (make-local-variable 'tool-bar-map) info-tool-bar-map) |
(set (make-local-variable 'tool-bar-map) info-tool-bar-map) |
2435 |
;; This is for the sake of the invisible text we use handling titles. |
;; This is for the sake of the invisible text we use handling titles. |
2436 |
(make-local-variable 'line-move-ignore-invisible) |
(make-local-variable 'line-move-ignore-invisible) |
2437 |
(setq line-move-ignore-invisible t) |
(setq line-move-ignore-invisible t) |
2438 |
(add-hook 'clone-buffer-hook 'Info-clone-buffer-hook nil t) |
(add-hook 'clone-buffer-hook 'Info-clone-buffer-hook nil t) |
2439 |
|
(add-hook 'change-major-mode-hook 'font-lock-defontify nil t) |
2440 |
(Info-set-mode-line) |
(Info-set-mode-line) |
2441 |
(run-hooks 'Info-mode-hook)) |
(run-hooks 'Info-mode-hook)) |
2442 |
|
|
2682 |
(put-text-property (match-beginning 1) (match-end 1) |
(put-text-property (match-beginning 1) (match-end 1) |
2683 |
'font-lock-face 'info-menu-header))))) |
'font-lock-face 'info-menu-header))))) |
2684 |
|
|
2685 |
|
(defvar Info-next-link-keymap |
2686 |
|
(let ((keymap (make-sparse-keymap))) |
2687 |
|
(define-key keymap [header-line mouse-1] 'Info-next) |
2688 |
|
(define-key keymap [header-line mouse-2] 'Info-next) |
2689 |
|
(define-key keymap [header-line down-mouse-1] 'ignore) |
2690 |
|
(define-key keymap [mouse-2] 'Info-next) |
2691 |
|
keymap) |
2692 |
|
"Keymap to put on the Next link in the text or the header line.") |
2693 |
|
|
2694 |
|
(defvar Info-prev-link-keymap |
2695 |
|
(let ((keymap (make-sparse-keymap))) |
2696 |
|
(define-key keymap [header-line mouse-1] 'Info-prev) |
2697 |
|
(define-key keymap [header-line mouse-2] 'Info-prev) |
2698 |
|
(define-key keymap [header-line down-mouse-1] 'ignore) |
2699 |
|
(define-key keymap [mouse-2] 'Info-prev) |
2700 |
|
keymap) |
2701 |
|
"Keymap to put on the Prev link in the text or the header line.") |
2702 |
|
|
2703 |
|
|
2704 |
|
(defvar Info-up-link-keymap |
2705 |
|
(let ((keymap (make-sparse-keymap))) |
2706 |
|
(define-key keymap [header-line mouse-1] 'Info-up) |
2707 |
|
(define-key keymap [header-line mouse-2] 'Info-up) |
2708 |
|
(define-key keymap [header-line down-mouse-1] 'ignore) |
2709 |
|
(define-key keymap [mouse-2] 'Info-up) |
2710 |
|
keymap) |
2711 |
|
"Keymap to put on the Up link in the text or the header line.") |
2712 |
|
|
2713 |
(defun Info-fontify-node () |
(defun Info-fontify-node () |
2714 |
;; Only fontify the node if it hasn't already been done. [We pass in |
;; Only fontify the node if it hasn't already been done. |
2715 |
;; LIMIT arg to `next-property-change' because it seems to search past |
(unless (let ((where (next-property-change (point-min)))) |
2716 |
;; (point-max).] |
(and where (not (= where (point-max))))) |
|
(unless (and (< (next-property-change (point-min) nil (point-max)) |
|
|
(point-max)) |
|
|
;; But do put the text properties if the local-map property |
|
|
;; is inconsistent with Info-use-header-line's value. |
|
|
(eq |
|
|
(= (next-single-property-change |
|
|
(point-min) 'local-map nil (point-max)) |
|
|
(point-max)) |
|
|
(null Info-use-header-line))) |
|
2717 |
(save-excursion |
(save-excursion |
2718 |
(let ((buffer-read-only nil) |
(let ((inhibit-read-only t) |
2719 |
(case-fold-search t)) |
(case-fold-search t) |
2720 |
|
paragraph-markers) |
2721 |
(goto-char (point-min)) |
(goto-char (point-min)) |
2722 |
(when (looking-at "^File: [^,: \t]+,?[ \t]+") |
(when (looking-at "^\\(File: [^,: \t]+,?[ \t]+\\)?") |
2723 |
(goto-char (match-end 0)) |
(goto-char (match-end 0)) |
2724 |
(while (looking-at "[ \t]*\\([^:, \t\n]+\\):[ \t]+\\([^:,\t\n]+\\),?") |
(while (looking-at "[ \t]*\\([^:, \t\n]+\\):[ \t]+\\([^:,\t\n]+\\),?") |
2725 |
(goto-char (match-end 0)) |
(goto-char (match-end 0)) |
2735 |
'help-echo |
'help-echo |
2736 |
(concat "Go to node " |
(concat "Go to node " |
2737 |
(buffer-substring nbeg nend))) |
(buffer-substring nbeg nend))) |
2738 |
;; Don't bind mouse events on the header line if we |
;; Always set up the text property keymap. |
2739 |
;; aren't going to display the header line. |
;; It will either be used in the buffer |
2740 |
(when Info-use-header-line |
;; or copied in the header line. |
2741 |
(let ((fun (cdr (assoc tag '(("Prev" . Info-prev) |
(put-text-property tbeg nend 'keymap |
2742 |
("Next" . Info-next) |
(cond |
2743 |
("Up" . Info-up)))))) |
((equal tag "Prev") Info-prev-link-keymap) |
2744 |
(when fun |
((equal tag "Next") Info-next-link-keymap) |
2745 |
(let ((keymap (make-sparse-keymap))) |
((equal tag "Up") Info-up-link-keymap)))))) |
2746 |
(define-key keymap [header-line mouse-1] fun) |
(when Info-use-header-line |
2747 |
(define-key keymap [header-line mouse-2] fun) |
(goto-char (point-min)) |
2748 |
(put-text-property tbeg nend 'local-map keymap))))) |
(let ((header-end (save-excursion (end-of-line) (point))) |
2749 |
(if (not Info-use-header-line) |
header) |
2750 |
;; In case they switched Info-use-header-line off |
;; If we find neither Next: nor Prev: link, show the entire |
2751 |
;; in the middle of an Info session, some text |
;; node header. Otherwise, don't show the File: and Node: |
2752 |
;; properties may have been left lying around from |
;; parts, to avoid wasting precious space on information that |
2753 |
;; past visits of this node. Remove them. |
;; is available in the mode line. |
2754 |
(remove-text-properties tbeg nend '(local-map nil))) |
(if (re-search-forward |
2755 |
)))) |
"\\(next\\|up\\|prev[ious]*\\): " |
2756 |
|
header-end t) |
2757 |
|
(progn |
2758 |
|
(goto-char (match-beginning 1)) |
2759 |
|
(setq header (buffer-substring (point) header-end))) |
2760 |
|
(if (re-search-forward "node:[ \t]*[^ \t]+[ \t]*" nil t) |
2761 |
|
(setq header |
2762 |
|
(concat "No next, prev or up links -- " |
2763 |
|
(buffer-substring (point) header-end))) |
2764 |
|
(setq header (buffer-substring (point) header-end)))) |
2765 |
|
|
2766 |
|
(put-text-property (point-min) (1+ (point-min)) |
2767 |
|
'header-line header) |
2768 |
|
;; Hide the part of the first line |
2769 |
|
;; that is in the header, if it is just part. |
2770 |
|
(unless (bobp) |
2771 |
|
;; Hide the punctuation at the end, too. |
2772 |
|
(skip-chars-backward " \t,") |
2773 |
|
(put-text-property (point) header-end 'invisible t))))) |
2774 |
(goto-char (point-min)) |
(goto-char (point-min)) |
2775 |
(while (re-search-forward "\n\\([^ \t\n].+\\)\n\\(\\*+\\|=+\\|-+\\|\\.+\\)$" |
(while (re-search-forward "\n\\([^ \t\n].+\\)\n\\(\\*+\\|=+\\|-+\\|\\.+\\)$" |
2776 |
nil t) |
nil t) |
2787 |
;; on frames that can display the font above. |
;; on frames that can display the font above. |
2788 |
(when (memq (framep (selected-frame)) '(x pc w32 mac)) |
(when (memq (framep (selected-frame)) '(x pc w32 mac)) |
2789 |
(add-text-properties (match-beginning 2) (1+ (match-end 2)) |
(add-text-properties (match-beginning 2) (1+ (match-end 2)) |
2790 |
'(invisible t intangible t)))) |
'(invisible t)))) |
2791 |
(goto-char (point-min)) |
(goto-char (point-min)) |
2792 |
(while (re-search-forward "\\*Note[ \n\t]+\\([^:]*\\):" nil t) |
(while (re-search-forward "\\(\\*Note[ \t]*\\)\n?[ \t]*\\([^:]*\\)\\(:[^.,:(]*\\(([^)]*)[^.,:]*\\)?[,:]?\n?\\)" nil t) |
2793 |
(if (= (char-after (1- (match-beginning 0))) ?\") ; hack |
(unless (= (char-after (1- (match-beginning 0))) ?\") ; hack |
2794 |
nil |
(let ((start (match-beginning 0)) |
2795 |
(add-text-properties (match-beginning 1) (match-end 1) |
(next (point)) |
2796 |
'(font-lock-face info-xref |
(hide-tag Info-hide-note-references) |
2797 |
mouse-face highlight |
other-tag) |
2798 |
help-echo "mouse-2: go to this node")))) |
(when hide-tag |
2799 |
|
;; *Note is often used where *note should have been |
2800 |
|
(goto-char start) |
2801 |
|
(skip-syntax-backward " ") |
2802 |
|
(setq other-tag |
2803 |
|
(cond |
2804 |
|
((or (<= (point) (point-min)) |
2805 |
|
(memq (char-after (1- (point))) '( ?\. ?! ))) |
2806 |
|
"See ") |
2807 |
|
((memq (char-after (1- (point))) '( ?\( ?\[ ?\{ ?\, ?\; ?\: )) |
2808 |
|
"see ") |
2809 |
|
(t nil))) |
2810 |
|
(goto-char next)) |
2811 |
|
(if hide-tag |
2812 |
|
(add-text-properties (match-beginning 1) (match-end 1) |
2813 |
|
'(invisible t))) |
2814 |
|
(add-text-properties (match-beginning 2) (match-end 2) |
2815 |
|
'(font-lock-face info-xref |
2816 |
|
mouse-face highlight |
2817 |
|
help-echo "mouse-2: go to this node")) |
2818 |
|
(when (eq Info-hide-note-references t) |
2819 |
|
(add-text-properties (match-beginning 3) (match-end 3) |
2820 |
|
'(invisible t))) |
2821 |
|
(when other-tag |
2822 |
|
(save-excursion |
2823 |
|
(goto-char (match-beginning 1)) |
2824 |
|
(insert other-tag))) |
2825 |
|
(when (or hide-tag (eq Info-hide-note-references t)) |
2826 |
|
(setq paragraph-markers (cons (set-marker (make-marker) start) |
2827 |
|
paragraph-markers)))))) |
2828 |
|
|
2829 |
|
(let ((fill-nobreak-invisible t)) |
2830 |
|
(goto-char (point-max)) |
2831 |
|
(while paragraph-markers |
2832 |
|
(let ((m (car paragraph-markers))) |
2833 |
|
(setq paragraph-markers (cdr paragraph-markers)) |
2834 |
|
(when (< m (point)) |
2835 |
|
(goto-char m) |
2836 |
|
(fill-paragraph nil) |
2837 |
|
(backward-paragraph 1)) |
2838 |
|
(set-marker m nil)))) |
2839 |
|
|
2840 |
(goto-char (point-min)) |
(goto-char (point-min)) |
2841 |
(if (and (search-forward "\n* Menu:" nil t) |
(if (and (search-forward "\n* Menu:" nil t) |
2842 |
(not (string-match "\\<Index\\>" Info-current-node)) |
(not (string-match "\\<Index\\>" Info-current-node)) |
2843 |
;; Don't take time to annotate huge menus |
;; Don't take time to annotate huge menus |
2844 |
(< (- (point-max) (point)) Info-fontify-maximum-menu-size)) |
(< (- (point-max) (point)) Info-fontify-maximum-menu-size)) |
2845 |
(let ((n 0)) |
(let ((n 0) |
2846 |
(while (re-search-forward "^\\* +\\([^:\t\n]*\\):" nil t) |
cont) |
2847 |
|
(while (re-search-forward "^\\* +\\([^:\t\n]*\\)\\(:[^.,:(]*\\(([^)]*)[^.,:]*\\)?[,:.][ \t]*\\)" nil t) |
2848 |
(setq n (1+ n)) |
(setq n (1+ n)) |
2849 |
(if (zerop (% n 3)) ; visual aids to help with 1-9 keys |
(if (zerop (% n 3)) ; visual aids to help with 1-9 keys |
2850 |
(put-text-property (match-beginning 0) |
(put-text-property (match-beginning 0) |
2853 |
(add-text-properties (match-beginning 1) (match-end 1) |
(add-text-properties (match-beginning 1) (match-end 1) |
2854 |
'(font-lock-face info-xref |
'(font-lock-face info-xref |
2855 |
mouse-face highlight |
mouse-face highlight |
2856 |
help-echo "mouse-2: go to this node"))))) |
help-echo "mouse-2: go to this node")) |
2857 |
|
(when (eq Info-hide-note-references t) |
2858 |
|
(add-text-properties (match-beginning 2) (match-end 2) |
2859 |
|
(list 'display |
2860 |
|
(make-string (max 2 (- 22 (- (match-end 1) (match-beginning 1)))) ? ))) |
2861 |
|
(setq cont (looking-at "[ \t]*[^\n]"))) |
2862 |
|
(if (eq Info-hide-note-references t) |
2863 |
|
(while (and (= (forward-line 1) 0) |
2864 |
|
(looking-at "\\([ \t]+\\)[^*\n]")) |
2865 |
|
(add-text-properties (match-beginning 1) (match-end 1) |
2866 |
|
(list 'display (make-string (+ 22 (if cont 4 2)) ? ))) |
2867 |
|
(setq cont t)))))) |
2868 |
|
|
2869 |
(Info-fontify-menu-headers) |
(Info-fontify-menu-headers) |
2870 |
(set-buffer-modified-p nil))))) |
(set-buffer-modified-p nil))))) |
2871 |
|
|