Mercurial > emacs
changeset 48135:2c6154347319
(Info-streamline-headings): New var.
(Info-dir-remove-duplicates): New fun.
(Info-insert-dir): Use it. Simplify the code with push,mapc,dolist.
(Info-select-node): Simplify handling of Info-header-line.
(Info-forward-node): Undo 2000/12/15 since we don't narrow any more.
(Info-mode): Set header-line-format once and for all.
(Info-fontify-node): Accept bogus first line with `File:' missing.
Only make first line invisible if Info-use-header-line.
Don't use `intangible': it's evil. Use inhibit-read-only.
(Info-follow-reference, Info-next-reference, Info-prev-reference)
(Info-try-follow-nearest-node): Don't bind inhibit-point-motion-hooks
since we don't use intangible any more.
author | Stefan Monnier <monnier@iro.umontreal.ca> |
---|---|
date | Sun, 03 Nov 2002 12:01:33 +0000 |
parents | ef2b87569c38 |
children | c102d9848214 |
files | lisp/info.el |
diffstat | 1 files changed, 132 insertions(+), 130 deletions(-) [+] |
line wrap: on
line diff
--- a/lisp/info.el Sun Nov 03 10:59:18 2002 +0000 +++ b/lisp/info.el Sun Nov 03 12:01:33 2002 +0000 @@ -815,10 +815,8 @@ (insert-file-contents file) (make-local-variable 'Info-dir-file-name) (setq Info-dir-file-name file) - (setq buffers (cons (current-buffer) buffers) - Info-dir-file-attributes - (cons (cons file attrs) - Info-dir-file-attributes))) + (push (current-buffer) buffers) + (push (cons file attrs) Info-dir-file-attributes)) (error (kill-buffer (current-buffer)))))))) (or (cdr dirs) (setq Info-dir-contents-directory (file-name-as-directory (car dirs)))) @@ -839,48 +837,34 @@ (insert-buffer buffer) ;; Look at each of the other buffers one by one. - (while others - (let ((other (car others)) - ;; Bind this in case the user sets it to nil. - (case-fold-search t) - this-buffer-nodes) + (dolist (other others) + (let (this-buffer-nodes) ;; In each, find all the menus. - (save-excursion - (set-buffer other) + (with-current-buffer other (goto-char (point-min)) ;; Find each menu, and add an elt to NODES for it. (while (re-search-forward "^\\* Menu:" nil t) - (let (beg nodename end) - (forward-line 1) - (while (and (eolp) (not (eobp))) - (forward-line 1)) - (setq beg (point)) - (or (search-backward "\n\^_" nil 'move) - (looking-at "\^_") - (signal 'search-failed (list "\n\^_"))) + (while (and (zerop (forward-line 1)) (eolp))) + (let ((beg (point)) + nodename end) + (re-search-backward "^\^_") (search-forward "Node: ") (setq nodename (Info-following-node-name)) (search-forward "\n\^_" nil 'move) (beginning-of-line) (setq end (point)) - (setq this-buffer-nodes - (cons (list nodename other beg end) - this-buffer-nodes)))) + (push (list nodename other beg end) this-buffer-nodes))) (if (assoc-ignore-case "top" this-buffer-nodes) (setq nodes (nconc this-buffer-nodes nodes)) (setq problems t) - (message "No `top' node in %s" Info-dir-file-name)))) - (setq others (cdr others))) + (message "No `top' node in %s" Info-dir-file-name))))) ;; Add to the main menu a menu item for each other node. - (let ((case-fold-search t) - (re-search-forward "^\\* Menu:"))) + (re-search-forward "^\\* Menu:") (forward-line 1) (let ((menu-items '("top")) - (nodes nodes) - (case-fold-search t) (end (save-excursion (search-forward "\^_" nil t) (point)))) - (while nodes - (let ((nodename (car (car nodes)))) + (dolist (node nodes) + (let ((nodename (car node))) (save-excursion (or (member (downcase nodename) menu-items) (re-search-forward (concat "^\\* +" @@ -889,13 +873,12 @@ end t) (progn (insert "* " nodename "::" "\n") - (setq menu-items (cons nodename menu-items)))))) - (setq nodes (cdr nodes)))) + (push nodename menu-items))))))) ;; Now take each node of each of the other buffers ;; and merge it into the main buffer. - (while nodes + (dolist (node nodes) (let ((case-fold-search t) - (nodename (car (car nodes)))) + (nodename (car node))) (goto-char (point-min)) ;; Find the like-named node in the main buffer. (if (re-search-forward (concat "^\^_.*\n.*Node: " @@ -911,12 +894,10 @@ (insert "\^_\nFile: dir\tNode: " nodename "\n\n* Menu:\n\n")) ;; Merge the text from the other buffer's menu ;; into the menu in the like-named node in the main buffer. - (apply 'insert-buffer-substring (cdr (car nodes)))) - (setq nodes (cdr nodes))) + (apply 'insert-buffer-substring (cdr node)))) + (Info-dir-remove-duplicates) ;; Kill all the buffers we just made. - (while buffers - (kill-buffer (car buffers)) - (setq buffers (cdr buffers))) + (mapc 'kill-buffer buffers) (goto-char (point-min)) (if problems (message "Composing main Info directory...problems encountered, see `*Messages*'") @@ -924,6 +905,70 @@ (setq Info-dir-contents (buffer-string))) (setq default-directory Info-dir-contents-directory)) +(defvar Info-streamline-headings + '(("Emacs" . "Emacs") + ("Programming" . "Programming") + ("Libraries" . "Libraries") + ("World Wide Web\\|Net Utilities" . "Net Utilities")) + "List of elements (RE . NAME) to merge headings matching RE to NAME.") + +(defun Info-dir-remove-duplicates () + (let (limit) + (goto-char (point-min)) + ;; Remove duplicate headings in the same menu. + (while (search-forward "\n* Menu:" nil t) + (setq limit (save-excursion (search-forward "\n" nil t))) + ;; Look for the next heading to unify. + (while (re-search-forward "^\\(\\w.*\\)\n\\*" limit t) + (let ((name (match-string 1)) + (start (match-beginning 0)) + (entries nil) re) + ;; Check whether this heading should be streamlined. + (save-match-data + (dolist (x Info-streamline-headings) + (when (string-match (car x) name) + (setq name (cdr x)) + (setq re (car x))))) + (if re (replace-match name t t nil 1)) + (goto-char (if (re-search-forward "^[^* \n\t]" limit t) + (match-beginning 0) + (or limit (point-max)))) + ;; Look for other headings of the same category and merge them. + (save-excursion + (while (re-search-forward "^\\(\\w.*\\)\n\\*" limit t) + (when (if re (save-match-data (string-match re (match-string 1))) + (equal name (match-string 1))) + (forward-line 0) + ;; Delete redundant heading. + (delete-region (match-beginning 0) (point)) + ;; Push the entries onto `text'. + (push + (delete-and-extract-region + (point) + (if (re-search-forward "^[^* \n\t]" nil t) + (match-beginning 0) + (or limit (point-max)))) entries)))) + ;; Insert the entries just found. + (while (= (line-beginning-position 0) (1- (point))) + (backward-char)) + (dolist (entry (nreverse entries)) + (insert entry) + (while (= (line-beginning-position 0) (1- (point))) + (delete-region (1- (point)) (point)))) + + ;; Now remove duplicate entries under the same heading. + (let ((seen nil) + (limit (point))) + (goto-char start) + (while (re-search-forward "^* \\([^:\n]+:\\(:\\|[^.\n]+\\).\\)" + limit 'move) + (let ((x (match-string 1))) + (if (member-ignore-case x seen) + (delete-region (match-beginning 0) + (progn (re-search-forward "^[^ \t]" nil t) + (goto-char (match-beginning 0)))) + (push x seen)))))))))) + ;; Note that on entry to this function the current-buffer must be the ;; *info* buffer; not the info tags buffer. (defun Info-read-subfile (nodepos) @@ -1014,17 +1059,7 @@ (point-max))) (if Info-enable-active-nodes (eval active-expression)) (Info-fontify-node) - (if Info-use-header-line - (progn - (setq Info-header-line - (get-text-property (point-min) 'header-line)) - (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)) - ) - (setq Info-header-line nil) - (setq header-line-format nil)) ; so the header line isn't displayed + (setq Info-header-line (get-text-property (point-min) 'header-line)) (run-hooks 'Info-selection-hook))))) (defun Info-set-mode-line () @@ -1251,10 +1286,6 @@ (save-excursion (save-restriction (goto-char (point-min)) -;;; (when Info-header-line -;;; ;; expose the header line in the buffer -;;; (widen) -;;; (forward-line -1)) (let ((bound (point))) (forward-line 1) (cond ((re-search-backward (concat name ":") bound t) @@ -1326,7 +1357,6 @@ (interactive (let ((completion-ignore-case t) (case-fold-search t) - (inhibit-point-motion-hooks t) completions default alt-default (start-point (point)) str i bol eol) (save-excursion ;; Store end and beginning of line. @@ -1391,7 +1421,6 @@ (error "No reference was specified")) (let (target beg i (str (concat "\\*note " (regexp-quote footnotename))) - (inhibit-point-motion-hooks t) (case-fold-search t)) (while (setq i (string-match " " str i)) (setq str (concat (substring str 0 i) "[ \t\n]+" (substring str (1+ i)))) @@ -1609,28 +1638,10 @@ (not (string-match "\\<index\\>" Info-current-node))) (Info-goto-node (Info-extract-menu-counting 1)) t) - ((save-excursion - (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)))) + ((save-excursion (search-backward "next:" nil t)) (Info-next) t) - ((and (save-excursion - (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)))) + ((and (save-excursion (search-backward "up:" nil t)) ;; Use string-equal, not equal, to ignore text props. (not (string-equal (downcase (Info-extract-pointer "up")) "top"))) @@ -1819,7 +1830,6 @@ "Move cursor to the next cross-reference or menu item in the node." (interactive) (let ((pat "\\*note[ \n\t]*\\([^:]*\\):\\|^\\* .*:") - (inhibit-point-motion-hooks t) (old-pt (point)) (case-fold-search t)) (or (eobp) (forward-char 1)) @@ -1840,7 +1850,6 @@ "Move cursor to the previous cross-reference or menu item in the node." (interactive) (let ((pat "\\*note[ \n\t]*\\([^:]*\\):\\|^\\* .*:") - (inhibit-point-motion-hooks t) (old-pt (point)) (case-fold-search t)) (or (re-search-backward pat nil t) @@ -2069,8 +2078,7 @@ ;; Common subroutine. (defun Info-try-follow-nearest-node () "Follow a node reference near point. Return non-nil if successful." - (let (node - (inhibit-point-motion-hooks t)) + (let (node) (cond ((setq node (Info-get-token (point) "\\*note[ \n]" "\\*note[ \n]\\([^:]*\\):")) @@ -2365,6 +2373,7 @@ (make-local-variable 'Info-history) (make-local-variable 'Info-index-alternatives) (make-local-variable 'Info-header-line) + (setq header-line-format (if Info-use-header-line 'Info-header-line)) (set (make-local-variable 'tool-bar-map) info-tool-bar-map) ;; This is for the sake of the invisible text we use handling titles. (make-local-variable 'line-move-ignore-invisible) @@ -2645,16 +2654,13 @@ "Keymap to put on the Up link in the text or the header line.") (defun Info-fontify-node () - ;; Only fontify the node if it hasn't already been done. [We pass in - ;; LIMIT arg to `next-property-change' because it seems to search past - ;; (point-max).] - (unless (< (next-property-change (point-min) nil (point-max)) - (point-max)) + ;; Only fontify the node if it hasn't already been done. + (unless (next-property-change (point-min)) (save-excursion - (let ((buffer-read-only nil) + (let ((inhibit-read-only t) (case-fold-search t)) (goto-char (point-min)) - (when (looking-at "^File: [^,: \t]+,?[ \t]+") + (when (looking-at "^\\(File: [^,: \t]+,?[ \t]+\\)?") (goto-char (match-end 0)) (while (looking-at "[ \t]*\\([^:, \t\n]+\\):[ \t]+\\([^:,\t\n]+\\),?") (goto-char (match-end 0)) @@ -2673,42 +2679,39 @@ ;; Always set up the text property keymap. ;; It will either be used in the buffer ;; or copied in the header line. - (cond ((equal tag "Prev") - (put-text-property tbeg nend 'keymap - Info-prev-link-keymap)) - ((equal tag "Next") - (put-text-property tbeg nend 'keymap - Info-next-link-keymap)) - ((equal tag "Up") - (put-text-property tbeg nend 'keymap - Info-up-link-keymap)))))) - (goto-char (point-min)) - (let ((header-end (save-excursion (end-of-line) (point))) - header) - ;; 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. - (if (re-search-forward - "\\(next\\|up\\|prev[ious]*\\): " - header-end t) - (progn - (goto-char (match-beginning 1)) - (setq header (buffer-substring (point) header-end))) - (if (re-search-forward "node:[ \t]*[^ \t]+[ \t]*" nil t) - (setq header - (concat "No next, prev or up links -- " - (buffer-substring (point) header-end))) - (setq header (buffer-substring (point) header-end)))) - - (put-text-property (point-min) (1+ (point-min)) - 'header-line header) - ;; Hide the part of the first line - ;; that is in the header, if it is just part. - (unless (bobp) - ;; Hide the punctuation at the end, too. - (skip-chars-backward " \t,") - (put-text-property (point) header-end 'invisible t)))) + (put-text-property tbeg nend 'keymap + (cond + ((equal tag "Prev") Info-prev-link-keymap) + ((equal tag "Next") Info-next-link-keymap) + ((equal tag "Up") Info-up-link-keymap)))))) + (when Info-use-header-line + (goto-char (point-min)) + (let ((header-end (save-excursion (end-of-line) (point))) + header) + ;; 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. + (if (re-search-forward + "\\(next\\|up\\|prev[ious]*\\): " + header-end t) + (progn + (goto-char (match-beginning 1)) + (setq header (buffer-substring (point) header-end))) + (if (re-search-forward "node:[ \t]*[^ \t]+[ \t]*" nil t) + (setq header + (concat "No next, prev or up links -- " + (buffer-substring (point) header-end))) + (setq header (buffer-substring (point) header-end)))) + + (put-text-property (point-min) (1+ (point-min)) + 'header-line header) + ;; Hide the part of the first line + ;; that is in the header, if it is just part. + (unless (bobp) + ;; Hide the punctuation at the end, too. + (skip-chars-backward " \t,") + (put-text-property (point) header-end 'invisible t))))) (goto-char (point-min)) (while (re-search-forward "\n\\([^ \t\n].+\\)\n\\(\\*+\\|=+\\|-+\\|\\.+\\)$" nil t) @@ -2725,7 +2728,7 @@ ;; on frames that can display the font above. (when (memq (framep (selected-frame)) '(x pc w32 mac)) (add-text-properties (match-beginning 2) (1+ (match-end 2)) - '(invisible t intangible t)))) + '(invisible t)))) (goto-char (point-min)) (while (re-search-forward "\\(\\*Note[ \n\t]+\\)\\([^:]*\\)\\(:[^.,:]*[,:]?\\)" nil t) (unless (= (char-after (1- (match-beginning 0))) ?\") ; hack @@ -2748,15 +2751,15 @@ (if hide-tag (add-text-properties (match-beginning 1) (match-end 1) (if other-tag - (list 'display other-tag 'intangible t) - '(invisible t intangible t)))) + (list 'display other-tag) + '(invisible t)))) (add-text-properties (match-beginning 2) (match-end 2) '(font-lock-face info-xref mouse-face highlight help-echo "mouse-2: go to this node")) (if (eq Info-hide-note-references t) (add-text-properties (match-beginning 3) (match-end 3) - '(invisible t intangible t)))))) + '(invisible t)))))) (goto-char (point-min)) (if (and (search-forward "\n* Menu:" nil t) @@ -2776,9 +2779,8 @@ help-echo "mouse-2: go to this node")) (if (eq Info-hide-note-references t) (add-text-properties (match-beginning 2) (match-end 2) - (list 'display - (make-string (max 2 (- 22 (- (match-end 1) (match-beginning 1)))) ? ) - 'intangible t)))))) + (list 'display + (make-string (max 2 (- 22 (- (match-end 1) (match-beginning 1)))) ? ))))))) (Info-fontify-menu-headers) (set-buffer-modified-p nil)))))