1
0
mirror of https://git.savannah.gnu.org/git/emacs.git synced 2025-02-05 20:43:08 +00:00

(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.
This commit is contained in:
Stefan Monnier 2002-11-03 12:01:33 +00:00
parent 538f9462d6
commit 6af7040d52

View File

@ -815,10 +815,8 @@ a case-insensitive match is tried."
(insert-file-contents file) (insert-file-contents file)
(make-local-variable 'Info-dir-file-name) (make-local-variable 'Info-dir-file-name)
(setq Info-dir-file-name file) (setq Info-dir-file-name file)
(setq buffers (cons (current-buffer) buffers) (push (current-buffer) buffers)
Info-dir-file-attributes (push (cons file attrs) Info-dir-file-attributes))
(cons (cons file attrs)
Info-dir-file-attributes)))
(error (kill-buffer (current-buffer)))))))) (error (kill-buffer (current-buffer))))))))
(or (cdr dirs) (setq Info-dir-contents-directory (or (cdr dirs) (setq Info-dir-contents-directory
(file-name-as-directory (car dirs)))) (file-name-as-directory (car dirs))))
@ -839,48 +837,34 @@ a case-insensitive match is tried."
(insert-buffer buffer) (insert-buffer buffer)
;; Look at each of the other buffers one by one. ;; Look at each of the other buffers one by one.
(while others (dolist (other others)
(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)
;; In each, find all the menus. ;; In each, find all the menus.
(save-excursion (with-current-buffer other
(set-buffer other)
(goto-char (point-min)) (goto-char (point-min))
;; Find each menu, and add an elt to NODES for it. ;; Find each menu, and add an elt to NODES for it.
(while (re-search-forward "^\\* Menu:" nil t) (while (re-search-forward "^\\* Menu:" nil t)
(let (beg nodename end) (while (and (zerop (forward-line 1)) (eolp)))
(forward-line 1) (let ((beg (point))
(while (and (eolp) (not (eobp))) nodename end)
(forward-line 1)) (re-search-backward "^\^_")
(setq beg (point))
(or (search-backward "\n\^_" nil 'move)
(looking-at "\^_")
(signal 'search-failed (list "\n\^_")))
(search-forward "Node: ") (search-forward "Node: ")
(setq nodename (Info-following-node-name)) (setq nodename (Info-following-node-name))
(search-forward "\n\^_" nil 'move) (search-forward "\n\^_" nil 'move)
(beginning-of-line) (beginning-of-line)
(setq end (point)) (setq end (point))
(setq this-buffer-nodes (push (list nodename other beg end) this-buffer-nodes)))
(cons (list nodename other beg end)
this-buffer-nodes))))
(if (assoc-ignore-case "top" this-buffer-nodes) (if (assoc-ignore-case "top" this-buffer-nodes)
(setq nodes (nconc this-buffer-nodes nodes)) (setq nodes (nconc this-buffer-nodes nodes))
(setq problems t) (setq problems t)
(message "No `top' node in %s" Info-dir-file-name)))) (message "No `top' node in %s" Info-dir-file-name)))))
(setq others (cdr others)))
;; Add to the main menu a menu item for each other node. ;; 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) (forward-line 1)
(let ((menu-items '("top")) (let ((menu-items '("top"))
(nodes nodes)
(case-fold-search t)
(end (save-excursion (search-forward "\^_" nil t) (point)))) (end (save-excursion (search-forward "\^_" nil t) (point))))
(while nodes (dolist (node nodes)
(let ((nodename (car (car nodes)))) (let ((nodename (car node)))
(save-excursion (save-excursion
(or (member (downcase nodename) menu-items) (or (member (downcase nodename) menu-items)
(re-search-forward (concat "^\\* +" (re-search-forward (concat "^\\* +"
@ -889,13 +873,12 @@ a case-insensitive match is tried."
end t) end t)
(progn (progn
(insert "* " nodename "::" "\n") (insert "* " nodename "::" "\n")
(setq menu-items (cons nodename menu-items)))))) (push nodename menu-items)))))))
(setq nodes (cdr nodes))))
;; Now take each node of each of the other buffers ;; Now take each node of each of the other buffers
;; and merge it into the main buffer. ;; and merge it into the main buffer.
(while nodes (dolist (node nodes)
(let ((case-fold-search t) (let ((case-fold-search t)
(nodename (car (car nodes)))) (nodename (car node)))
(goto-char (point-min)) (goto-char (point-min))
;; Find the like-named node in the main buffer. ;; Find the like-named node in the main buffer.
(if (re-search-forward (concat "^\^_.*\n.*Node: " (if (re-search-forward (concat "^\^_.*\n.*Node: "
@ -911,12 +894,10 @@ a case-insensitive match is tried."
(insert "\^_\nFile: dir\tNode: " nodename "\n\n* Menu:\n\n")) (insert "\^_\nFile: dir\tNode: " nodename "\n\n* Menu:\n\n"))
;; Merge the text from the other buffer's menu ;; Merge the text from the other buffer's menu
;; into the menu in the like-named node in the main buffer. ;; into the menu in the like-named node in the main buffer.
(apply 'insert-buffer-substring (cdr (car nodes)))) (apply 'insert-buffer-substring (cdr node))))
(setq nodes (cdr nodes))) (Info-dir-remove-duplicates)
;; Kill all the buffers we just made. ;; Kill all the buffers we just made.
(while buffers (mapc 'kill-buffer buffers)
(kill-buffer (car buffers))
(setq buffers (cdr buffers)))
(goto-char (point-min)) (goto-char (point-min))
(if problems (if problems
(message "Composing main Info directory...problems encountered, see `*Messages*'") (message "Composing main Info directory...problems encountered, see `*Messages*'")
@ -924,6 +905,70 @@ a case-insensitive match is tried."
(setq Info-dir-contents (buffer-string))) (setq Info-dir-contents (buffer-string)))
(setq default-directory Info-dir-contents-directory)) (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 ;; Note that on entry to this function the current-buffer must be the
;; *info* buffer; not the info tags buffer. ;; *info* buffer; not the info tags buffer.
(defun Info-read-subfile (nodepos) (defun Info-read-subfile (nodepos)
@ -1014,17 +1059,7 @@ Bind this in case the user sets it to nil."
(point-max))) (point-max)))
(if Info-enable-active-nodes (eval active-expression)) (if Info-enable-active-nodes (eval active-expression))
(Info-fontify-node) (Info-fontify-node)
(if Info-use-header-line (setq Info-header-line (get-text-property (point-min) '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
(run-hooks 'Info-selection-hook))))) (run-hooks 'Info-selection-hook)))))
(defun Info-set-mode-line () (defun Info-set-mode-line ()
@ -1251,10 +1286,6 @@ Bind this in case the user sets it to nil."
(save-excursion (save-excursion
(save-restriction (save-restriction
(goto-char (point-min)) (goto-char (point-min))
;;; (when Info-header-line
;;; ;; expose the header line in the buffer
;;; (widen)
;;; (forward-line -1))
(let ((bound (point))) (let ((bound (point)))
(forward-line 1) (forward-line 1)
(cond ((re-search-backward (concat name ":") bound t) (cond ((re-search-backward (concat name ":") bound t)
@ -1326,7 +1357,6 @@ FOOTNOTENAME may be an abbreviation of the reference name."
(interactive (interactive
(let ((completion-ignore-case t) (let ((completion-ignore-case t)
(case-fold-search t) (case-fold-search t)
(inhibit-point-motion-hooks t)
completions default alt-default (start-point (point)) str i bol eol) completions default alt-default (start-point (point)) str i bol eol)
(save-excursion (save-excursion
;; Store end and beginning of line. ;; Store end and beginning of line.
@ -1391,7 +1421,6 @@ FOOTNOTENAME may be an abbreviation of the reference name."
(error "No reference was specified")) (error "No reference was specified"))
(let (target beg i (str (concat "\\*note " (regexp-quote footnotename))) (let (target beg i (str (concat "\\*note " (regexp-quote footnotename)))
(inhibit-point-motion-hooks t)
(case-fold-search t)) (case-fold-search t))
(while (setq i (string-match " " str i)) (while (setq i (string-match " " str i))
(setq str (concat (substring str 0 i) "[ \t\n]+" (substring str (1+ i)))) (setq str (concat (substring str 0 i) "[ \t\n]+" (substring str (1+ i))))
@ -1609,28 +1638,10 @@ N is the digit argument used to invoke this command."
(not (string-match "\\<index\\>" Info-current-node))) (not (string-match "\\<index\\>" Info-current-node)))
(Info-goto-node (Info-extract-menu-counting 1)) (Info-goto-node (Info-extract-menu-counting 1))
t) t)
((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))))
(Info-next) (Info-next)
t) t)
((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))))
;; Use string-equal, not equal, to ignore text props. ;; Use string-equal, not equal, to ignore text props.
(not (string-equal (downcase (Info-extract-pointer "up")) (not (string-equal (downcase (Info-extract-pointer "up"))
"top"))) "top")))
@ -1819,7 +1830,6 @@ parent node."
"Move cursor to the next cross-reference or menu item in the node." "Move cursor to the next cross-reference or menu item in the node."
(interactive) (interactive)
(let ((pat "\\*note[ \n\t]*\\([^:]*\\):\\|^\\* .*:") (let ((pat "\\*note[ \n\t]*\\([^:]*\\):\\|^\\* .*:")
(inhibit-point-motion-hooks t)
(old-pt (point)) (old-pt (point))
(case-fold-search t)) (case-fold-search t))
(or (eobp) (forward-char 1)) (or (eobp) (forward-char 1))
@ -1840,7 +1850,6 @@ parent node."
"Move cursor to the previous cross-reference or menu item in the node." "Move cursor to the previous cross-reference or menu item in the node."
(interactive) (interactive)
(let ((pat "\\*note[ \n\t]*\\([^:]*\\):\\|^\\* .*:") (let ((pat "\\*note[ \n\t]*\\([^:]*\\):\\|^\\* .*:")
(inhibit-point-motion-hooks t)
(old-pt (point)) (old-pt (point))
(case-fold-search t)) (case-fold-search t))
(or (re-search-backward pat nil t) (or (re-search-backward pat nil t)
@ -2069,8 +2078,7 @@ If no reference to follow, moves to the next node, or up if none."
;; Common subroutine. ;; Common subroutine.
(defun Info-try-follow-nearest-node () (defun Info-try-follow-nearest-node ()
"Follow a node reference near point. Return non-nil if successful." "Follow a node reference near point. Return non-nil if successful."
(let (node (let (node)
(inhibit-point-motion-hooks t))
(cond (cond
((setq node (Info-get-token (point) "\\*note[ \n]" ((setq node (Info-get-token (point) "\\*note[ \n]"
"\\*note[ \n]\\([^:]*\\):")) "\\*note[ \n]\\([^:]*\\):"))
@ -2365,6 +2373,7 @@ Advanced commands:
(make-local-variable 'Info-history) (make-local-variable 'Info-history)
(make-local-variable 'Info-index-alternatives) (make-local-variable 'Info-index-alternatives)
(make-local-variable 'Info-header-line) (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) (set (make-local-variable 'tool-bar-map) info-tool-bar-map)
;; 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.
(make-local-variable 'line-move-ignore-invisible) (make-local-variable 'line-move-ignore-invisible)
@ -2645,16 +2654,13 @@ the variable `Info-file-list-for-emacs'."
"Keymap to put on the Up link in the text or the header line.") "Keymap to put on the Up link in the text or the header line.")
(defun Info-fontify-node () (defun Info-fontify-node ()
;; 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.
;; LIMIT arg to `next-property-change' because it seems to search past (unless (next-property-change (point-min))
;; (point-max).]
(unless (< (next-property-change (point-min) nil (point-max))
(point-max))
(save-excursion (save-excursion
(let ((buffer-read-only nil) (let ((inhibit-read-only t)
(case-fold-search t)) (case-fold-search t))
(goto-char (point-min)) (goto-char (point-min))
(when (looking-at "^File: [^,: \t]+,?[ \t]+") (when (looking-at "^\\(File: [^,: \t]+,?[ \t]+\\)?")
(goto-char (match-end 0)) (goto-char (match-end 0))
(while (looking-at "[ \t]*\\([^:, \t\n]+\\):[ \t]+\\([^:,\t\n]+\\),?") (while (looking-at "[ \t]*\\([^:, \t\n]+\\):[ \t]+\\([^:,\t\n]+\\),?")
(goto-char (match-end 0)) (goto-char (match-end 0))
@ -2673,42 +2679,39 @@ the variable `Info-file-list-for-emacs'."
;; Always set up the text property keymap. ;; Always set up the text property keymap.
;; It will either be used in the buffer ;; It will either be used in the buffer
;; or copied in the header line. ;; or copied in the header line.
(cond ((equal tag "Prev") (put-text-property tbeg nend 'keymap
(put-text-property tbeg nend 'keymap (cond
Info-prev-link-keymap)) ((equal tag "Prev") Info-prev-link-keymap)
((equal tag "Next") ((equal tag "Next") Info-next-link-keymap)
(put-text-property tbeg nend 'keymap ((equal tag "Up") Info-up-link-keymap))))))
Info-next-link-keymap)) (when Info-use-header-line
((equal tag "Up") (goto-char (point-min))
(put-text-property tbeg nend 'keymap (let ((header-end (save-excursion (end-of-line) (point)))
Info-up-link-keymap)))))) header)
(goto-char (point-min)) ;; If we find neither Next: nor Prev: link, show the entire
(let ((header-end (save-excursion (end-of-line) (point))) ;; node header. Otherwise, don't show the File: and Node:
header) ;; parts, to avoid wasting precious space on information that
;; If we find neither Next: nor Prev: link, show the entire ;; is available in the mode line.
;; node header. Otherwise, don't show the File: and Node: (if (re-search-forward
;; parts, to avoid wasting precious space on information that "\\(next\\|up\\|prev[ious]*\\): "
;; is available in the mode line. header-end t)
(if (re-search-forward (progn
"\\(next\\|up\\|prev[ious]*\\): " (goto-char (match-beginning 1))
header-end t) (setq header (buffer-substring (point) header-end)))
(progn (if (re-search-forward "node:[ \t]*[^ \t]+[ \t]*" nil t)
(goto-char (match-beginning 1)) (setq header
(setq header (buffer-substring (point) header-end))) (concat "No next, prev or up links -- "
(if (re-search-forward "node:[ \t]*[^ \t]+[ \t]*" nil t) (buffer-substring (point) header-end)))
(setq header (setq header (buffer-substring (point) header-end))))
(concat "No next, prev or up links -- "
(buffer-substring (point) header-end))) (put-text-property (point-min) (1+ (point-min))
(setq header (buffer-substring (point) header-end)))) 'header-line header)
;; Hide the part of the first line
(put-text-property (point-min) (1+ (point-min)) ;; that is in the header, if it is just part.
'header-line header) (unless (bobp)
;; Hide the part of the first line ;; Hide the punctuation at the end, too.
;; that is in the header, if it is just part. (skip-chars-backward " \t,")
(unless (bobp) (put-text-property (point) header-end 'invisible t)))))
;; Hide the punctuation at the end, too.
(skip-chars-backward " \t,")
(put-text-property (point) header-end 'invisible t))))
(goto-char (point-min)) (goto-char (point-min))
(while (re-search-forward "\n\\([^ \t\n].+\\)\n\\(\\*+\\|=+\\|-+\\|\\.+\\)$" (while (re-search-forward "\n\\([^ \t\n].+\\)\n\\(\\*+\\|=+\\|-+\\|\\.+\\)$"
nil t) nil t)
@ -2725,7 +2728,7 @@ the variable `Info-file-list-for-emacs'."
;; on frames that can display the font above. ;; on frames that can display the font above.
(when (memq (framep (selected-frame)) '(x pc w32 mac)) (when (memq (framep (selected-frame)) '(x pc w32 mac))
(add-text-properties (match-beginning 2) (1+ (match-end 2)) (add-text-properties (match-beginning 2) (1+ (match-end 2))
'(invisible t intangible t)))) '(invisible t))))
(goto-char (point-min)) (goto-char (point-min))
(while (re-search-forward "\\(\\*Note[ \n\t]+\\)\\([^:]*\\)\\(:[^.,:]*[,:]?\\)" nil t) (while (re-search-forward "\\(\\*Note[ \n\t]+\\)\\([^:]*\\)\\(:[^.,:]*[,:]?\\)" nil t)
(unless (= (char-after (1- (match-beginning 0))) ?\") ; hack (unless (= (char-after (1- (match-beginning 0))) ?\") ; hack
@ -2748,15 +2751,15 @@ the variable `Info-file-list-for-emacs'."
(if hide-tag (if hide-tag
(add-text-properties (match-beginning 1) (match-end 1) (add-text-properties (match-beginning 1) (match-end 1)
(if other-tag (if other-tag
(list 'display other-tag 'intangible t) (list 'display other-tag)
'(invisible t intangible t)))) '(invisible t))))
(add-text-properties (match-beginning 2) (match-end 2) (add-text-properties (match-beginning 2) (match-end 2)
'(font-lock-face info-xref '(font-lock-face info-xref
mouse-face highlight mouse-face highlight
help-echo "mouse-2: go to this node")) help-echo "mouse-2: go to this node"))
(if (eq Info-hide-note-references t) (if (eq Info-hide-note-references t)
(add-text-properties (match-beginning 3) (match-end 3) (add-text-properties (match-beginning 3) (match-end 3)
'(invisible t intangible t)))))) '(invisible t))))))
(goto-char (point-min)) (goto-char (point-min))
(if (and (search-forward "\n* Menu:" nil t) (if (and (search-forward "\n* Menu:" nil t)
@ -2776,9 +2779,8 @@ the variable `Info-file-list-for-emacs'."
help-echo "mouse-2: go to this node")) help-echo "mouse-2: go to this node"))
(if (eq Info-hide-note-references t) (if (eq Info-hide-note-references t)
(add-text-properties (match-beginning 2) (match-end 2) (add-text-properties (match-beginning 2) (match-end 2)
(list 'display (list 'display
(make-string (max 2 (- 22 (- (match-end 1) (match-beginning 1)))) ? ) (make-string (max 2 (- 22 (- (match-end 1) (match-beginning 1)))) ? )))))))
'intangible t))))))
(Info-fontify-menu-headers) (Info-fontify-menu-headers)
(set-buffer-modified-p nil))))) (set-buffer-modified-p nil)))))