From mboxrd@z Thu Jan 1 00:00:00 1970 Path: main.gmane.org!not-for-mail From: Juri Linkov Newsgroups: gmane.emacs.devel Subject: Info enhancements Date: Mon, 01 Dec 2003 12:38:15 +0200 Organization: JURTA Sender: emacs-devel-bounces+emacs-devel=quimby.gnus.org@gnu.org Message-ID: <87smk4zuvv.fsf@mail.jurta.org> NNTP-Posting-Host: deer.gmane.org Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii X-Trace: sea.gmane.org 1070301293 29190 80.91.224.253 (1 Dec 2003 17:54:53 GMT) X-Complaints-To: usenet@sea.gmane.org NNTP-Posting-Date: Mon, 1 Dec 2003 17:54:53 +0000 (UTC) Original-X-From: emacs-devel-bounces+emacs-devel=quimby.gnus.org@gnu.org Mon Dec 01 18:54:48 2003 Return-path: Original-Received: from quimby.gnus.org ([80.91.224.244]) by deer.gmane.org with esmtp (Exim 3.35 #1 (Debian)) id 1AQsG0-0003R5-00 for ; Mon, 01 Dec 2003 18:54:48 +0100 Original-Received: from monty-python.gnu.org ([199.232.76.173]) by quimby.gnus.org with esmtp (Exim 3.35 #1 (Debian)) id 1AQsFz-0002Rs-00 for ; Mon, 01 Dec 2003 18:54:48 +0100 Original-Received: from localhost ([127.0.0.1] helo=monty-python.gnu.org) by monty-python.gnu.org with esmtp (Exim 4.24) id 1AQryX-0007Sn-Uw for emacs-devel@quimby.gnus.org; Mon, 01 Dec 2003 12:36:45 -0500 Original-Received: from list by monty-python.gnu.org with tmda-scanned (Exim 4.24) id 1AQnVD-0000tv-Ek for emacs-devel@gnu.org; Mon, 01 Dec 2003 07:50:11 -0500 Original-Received: from mail by monty-python.gnu.org with spam-scanned (Exim 4.24) id 1AQmiU-0003Y1-62 for emacs-devel@gnu.org; Mon, 01 Dec 2003 07:00:21 -0500 Original-Received: from [64.246.52.22] (helo=ns5.tangramltd.com) by monty-python.gnu.org with esmtp (TLSv1:DES-CBC3-SHA:168) (Exim 4.24) id 1AQmSh-0002Bt-Ae for emacs-devel@gnu.org; Mon, 01 Dec 2003 06:43:31 -0500 Original-Received: from 80-235-34-55-dsl.mus.estpak.ee ([80.235.34.55] helo=mail.jurta.org) by ns5.tangramltd.com with esmtp (Exim 4.20) id 1AQlV9-0005yi-0g for emacs-devel@gnu.org; Mon, 01 Dec 2003 12:41:59 +0200 Original-To: emacs-devel@gnu.org User-Agent: Gnus/5.1003 (Gnus v5.10.3) Emacs/21.3.50 (gnu/linux) X-AntiAbuse: This header was added to track abuse, please include it with any abuse report X-AntiAbuse: Primary Hostname - ns5.tangramltd.com X-AntiAbuse: Original Domain - gnu.org X-AntiAbuse: Originator/Caller UID/GID - [0 0] / [47 12] X-AntiAbuse: Sender Address Domain - jurta.org X-BeenThere: emacs-devel@gnu.org X-Mailman-Version: 2.1.2 Precedence: list List-Id: Emacs development discussions. List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: emacs-devel-bounces+emacs-devel=quimby.gnus.org@gnu.org Xref: main.gmane.org gmane.emacs.devel:18246 X-Report-Spam: http://spam.gmane.org/gmane.emacs.devel:18246 I would like to submit a patch that fixes some problems in the Emacs Info reader and adds features most web browsers already have. This patch don't change the existing Info file format. It improves usability of the Emacs Info reader with the current Info file format. Any comments are welcome. New features: - distinguish visited nodes from unvisited by displaying their references in a different color. Standard colors of web browsers are used: blue - for unvisited links, magenta - for visited links. - show full history list or tree of visited Info nodes. This list is displayed in the Info buffer using "*Note" references, so standard Info functions can be used for navigation to visited nodes from the history buffer. - http links are fontified and available for navigation by calling the `browse-url' function. - a new argument `fork' is added to Info-follow-reference, Info-follow-nearest-node and Info-try-follow-nearest-node functions, so if these functions are called interactively with a prefix arg, they show the node in a new info buffer. This feature is copied from the `Info-menu' which works only for menu items. But this is useful for references too, especially for references that carry out of the current manual. - use reference names to move point to the place within the current node where reference name is defined. For example, by following the reference "*Note file-coding-system-alist: Default Coding Systems," Info finds a node with the name "Default Coding Systems" and moves point to the line where reference name "file-coding-system-alist" is defined. This feature uses the function `Info-find-index-name' that currently works only for the function `Info-index'. Now it works also for index items and cross references. This feature solves problems in the Glossary node of the Emacs manual, where links to the same node are marked by the "(q.v.)" or "See `text'". Such text can be replaced in references to the same node with this text as a reference name. For example, the text "is shared by an indirect buffer (q.v.@:)" can be replaced with "is shared by an @ref{Glossary,indirect buffer}", and text "See `filling.'" can be replaced with "@xref{Glossary,filling}.". Following such a reference will move point to the place in the same node where this glossary term is defined. - rebind `M-s' key to a new function `Info-search-next' that searches for another occurrence of regular expression from a previous `Info-search' command (key `s'). Pressing only one key to repeat a search is more convenient than pressing two keys (`s RET'). Fixed problems: - don't hide the newline (with following whitespace) in references when Info-hide-note-references is t. This fixes the problem where hidden newlines cause too long (and truncated) lines. - don't hide the name of external Info file in references in case when Info-hide-note-references is t and references lead outside the current Info file. It's important for user to know about such situation. - don't insert the text "See" instead of "Note" because inserting a new text in Info buffer breaks the stored point positions. This bug can be observed by calling `Info-last', `Info-search' where point is moved with some offset to its correct position (the offset is the sum of lengths of strings "See" inserted in the buffer above the point). - add a character ` to the list of prefix characters used to escape the literal meaning of the text "*Note". The wrong fontification caused by this bug can be observed in (info "(info)Cross-refs"). Index: emacs/lisp/info.el =================================================================== RCS file: /cvsroot/emacs/emacs/lisp/info.el,v retrieving revision 1.374 diff -c -r1.374 info.el *** emacs/lisp/info.el 7 Oct 2003 00:04:45 -0000 1.374 --- emacs/lisp/info.el 1 Dec 2003 11:48:03 -0000 *************** *** 48,53 **** --- 48,60 ---- "List of info nodes user has visited. Each element of list is a list (FILENAME NODENAME BUFFERPOS).") + (defvar Info-history-tree nil + "Tree of info nodes user has visited. + Each element of list is a list (FILENAME NODENAME PARENT-INDEX).") + + (defvar Info-history-node -1 + "Position of the current node on the info nodes tree user has visited.") + (defcustom Info-enable-edit nil "*Non-nil means the \\\\[Info-edit] command in Info can edit the current node. This is convenient if you want to write info files by hand. *************** *** 76,87 **** :group 'info) (defface info-xref ! '((((class color) (background light)) (:foreground "magenta4" :weight bold)) ! (((class color) (background dark)) (:foreground "cyan" :weight bold)) ! (t (:weight bold))) "Face for Info cross-references." :group 'info) (defcustom Info-fontify-maximum-menu-size 100000 "*Maximum size of menu to fontify if `font-lock-mode' is non-nil." :type 'integer --- 83,107 ---- :group 'info) (defface info-xref ! '((((class color) (background light)) (:foreground "blue")) ! (((class color) (background dark)) (:foreground "cyan")) ! (t (:underline t))) "Face for Info cross-references." :group 'info) + (defface info-xref-visited + '((((class color) (background light)) (:foreground "magenta4")) + (((class color) (background dark)) (:foreground "magenta4")) + (t (:underline t))) + "Face for visited Info cross-references." + :group 'info) + + (defcustom Info-visited-nodes t + "*Non-nil means to fontify visited nodes in a different color." + :version "21.4" + :type 'boolean + :group 'info) + (defcustom Info-fontify-maximum-menu-size 100000 "*Maximum size of menu to fontify if `font-lock-mode' is non-nil." :type 'integer *************** *** 155,161 **** (defcustom Info-hide-note-references t "*If non-nil, hide the tag and section reference in *note and * menu items. - Also replaces the \"*note\" text with \"see\". If value is non-nil but not t, the reference section is still shown." :version "21.4" :type '(choice (const :tag "No reformatting" nil) --- 175,180 ---- *************** *** 205,210 **** --- 224,232 ---- (defvar Info-index-alternatives nil "List of possible matches for last `Info-index' command.") + (defvar Info-reference-name nil + "Name of the current reference.") + (defvar Info-standalone nil "Non-nil if Emacs was started solely as an Info browser.") *************** *** 787,793 **** nodename))) (Info-select-node) ! (goto-char (or anchorpos (point-min)))))) ;; If we did not finish finding the specified node, ;; go back to the previous one. (or Info-current-node no-going-back (null Info-history) --- 809,820 ---- nodename))) (Info-select-node) ! (goto-char (or anchorpos (point-min))) ! ! ;; Move point to the place where the referer name points to ! (when Info-reference-name ! (Info-find-index-name Info-reference-name) ! (setq Info-reference-name nil))))) ;; If we did not finish finding the specified node, ;; go back to the previous one. (or Info-current-node no-going-back (null Info-history) *************** *** 1176,1181 **** --- 1203,1225 ---- (if Info-enable-active-nodes (eval active-expression)) (Info-fontify-node) (Info-display-images-node) + + ;; Add a new history node or use old node from the history tree + (let ((tree Info-history-tree) + (i 0) res) + (while tree + (if (and (equal (nth 0 (car tree)) Info-current-file) + (equal (nth 1 (car tree)) Info-current-node)) + (setq res i tree nil)) + (setq tree (cdr tree) i (1+ i))) + (if res + (setq Info-history-node res) + (setq Info-history-tree + (nconc Info-history-tree + (list (list Info-current-file Info-current-node + Info-history-node))) + Info-history-node (1- (length Info-history-tree))))) + (run-hooks 'Info-selection-hook))))) (defun Info-set-mode-line () *************** *** 1207,1212 **** --- 1251,1258 ---- (if fork (set-buffer (clone-buffer (concat "*info-" (if (stringp fork) fork nodename) "*") t))) + (if (equal (buffer-name) "*info-history*") + (switch-to-buffer "*info*")) (let (filename) (string-match "\\s *\\((\\s *\\([^\t)]*\\)\\s *)\\s *\\|\\)\\(.*\\)" nodename) *************** *** 1409,1414 **** --- 1455,1468 ---- (equal ofile Info-current-file)) (setq Info-history (cons (list ofile onode opoint) Info-history)))))) + + (defun Info-search-next () + "Search for next regexp from a previous `Info-search' command." + (interactive) + (if Info-search-history + (Info-search (car Info-search-history)) + ;; If no history then read search string in Info-search + (call-interactively 'Info-search))) (defun Info-extract-pointer (name &optional errorname) "Extract the value of the node-pointer named NAME. *************** *** 1481,1495 **** (setq Info-history (cdr Info-history)) (goto-char opoint))) ;;;###autoload (defun Info-directory () "Go to the Info directory node." (interactive) (Info-find-node "dir" "top")) ! (defun Info-follow-reference (footnotename) "Follow cross reference named FOOTNOTENAME to the node it refers to. ! FOOTNOTENAME may be an abbreviation of the reference name." (interactive (let ((completion-ignore-case t) (case-fold-search t) --- 1535,1594 ---- (setq Info-history (cdr Info-history)) (goto-char opoint))) + ;;;###autoload (add-hook 'same-window-buffer-names "*info-history*") + + (defun Info-history-buffer (&optional tree-p) + "Create the buffer *info-history* with references to visited nodes. + Optional argument TREE-P creates a tree of nodes; the default + creates the plain list of nodes." + (interactive "P") + (let ((curr-node Info-history-node) + p) + (pop-to-buffer + (with-current-buffer (get-buffer-create "*info-history*") + (let ((Info-hide-note-references t) + (Info-visited-nodes t) + (inhibit-read-only t)) + (erase-buffer) + (goto-char (point-min)) + (setq p (Info-insert-history-tree -1 0 (or curr-node 0) tree-p)) + (if (not (bobp)) (Info-fontify-node)) + (or (eq major-mode 'Info-mode) (Info-mode)) + (let ((Info-current-file "history") + (Info-current-node "History")) + (Info-set-mode-line)) + (current-buffer)))) + (goto-char (or p (point-min))))) + + (defun Info-insert-history-tree (index indent curr-node tree-p) + "Insert the tree or list of references to visited nodes. + Return the position of the current node on the generated tree." + (let ((tree Info-history-tree) + (i 0) p) + (while tree + (when (or (null tree-p) (eq (nth 2 (car tree)) index)) + (if tree-p (insert (make-string indent ?\040))) + (if (eq i curr-node) (setq p (point))) + (insert "*Note " (nth 1 (car tree)) ": (" + (file-name-nondirectory (nth 0 (car tree))) + ")" (nth 1 (car tree)) ".\n") + (if tree-p (setq p (or (Info-insert-history-tree + i (1+ indent) curr-node tree-p) p)))) + (setq tree (cdr tree) i (1+ i))) + p)) + ;;;###autoload (defun Info-directory () "Go to the Info directory node." (interactive) (Info-find-node "dir" "top")) ! (defun Info-follow-reference (footnotename &optional fork) "Follow cross reference named FOOTNOTENAME to the node it refers to. ! FOOTNOTENAME may be an abbreviation of the reference name. ! If FORK is non-nil (interactively with a prefix arg), show the node in ! a new info buffer. If FORK is a string, it is the name to use for the ! new buffer." (interactive (let ((completion-ignore-case t) (case-fold-search t) *************** *** 1539,1545 **** "Follow reference named: ") completions nil t))) (list (if (equal input "") ! default input))) (error "No cross-references in this node")))) (unless footnotename --- 1638,1644 ---- "Follow reference named: ") completions nil t))) (list (if (equal input "") ! default input) current-prefix-arg)) (error "No cross-references in this node")))) (unless footnotename *************** *** 1561,1567 **** (setq target (concat (substring target 0 i) " " (substring target (match-end 0)))) (setq i (+ i 1))) ! (Info-goto-node target))) (defconst Info-menu-entry-name-re "\\(?:[^:]\\|:[^:,.;() \t\n]\\)*" ;; We allow newline because this is also used in Info-follow-reference, --- 1660,1666 ---- (setq target (concat (substring target 0 i) " " (substring target (match-end 0)))) (setq i (+ i 1))) ! (Info-goto-node target fork))) (defconst Info-menu-entry-name-re "\\(?:[^:]\\|:[^:,.;() \t\n]\\)*" ;; We allow newline because this is also used in Info-follow-reference, *************** *** 1968,1974 **** (defun Info-next-reference (&optional recur) "Move cursor to the next cross-reference or menu item in the node." (interactive) ! (let ((pat "\\*note[ \n\t]*\\([^:]*\\):\\|^\\* .*:") (old-pt (point)) (case-fold-search t)) (or (eobp) (forward-char 1)) --- 2067,2073 ---- (defun Info-next-reference (&optional recur) "Move cursor to the next cross-reference or menu item in the node." (interactive) ! (let ((pat "\\*note[ \n\t]*\\([^:]*\\):\\|^\\* .*:\\|http://") (old-pt (point)) (case-fold-search t)) (or (eobp) (forward-char 1)) *************** *** 1988,1994 **** (defun Info-prev-reference (&optional recur) "Move cursor to the previous cross-reference or menu item in the node." (interactive) ! (let ((pat "\\*note[ \n\t]*\\([^:]*\\):\\|^\\* .*:") (old-pt (point)) (case-fold-search t)) (or (re-search-backward pat nil t) --- 2087,2093 ---- (defun Info-prev-reference (&optional recur) "Move cursor to the previous cross-reference or menu item in the node." (interactive) ! (let ((pat "\\*note[ \n\t]*\\([^:]*\\):\\|^\\* .*:\\|http://") (old-pt (point)) (case-fold-search t)) (or (re-search-backward pat nil t) *************** *** 2209,2220 **** (save-excursion (forward-line 1) (eobp)) (Info-next-preorder))) ! (defun Info-follow-nearest-node () "Follow a node reference near point. If point is on a reference, follow that reference. Otherwise, if point is in a menu item description, follow that menu item." ! (interactive) ! (or (Info-try-follow-nearest-node) (when (save-excursion (search-backward "\n* menu:" nil t)) (save-excursion --- 2308,2319 ---- (save-excursion (forward-line 1) (eobp)) (Info-next-preorder))) ! (defun Info-follow-nearest-node (&optional fork) "Follow a node reference near point. If point is on a reference, follow that reference. Otherwise, if point is in a menu item description, follow that menu item." ! (interactive "P") ! (or (Info-try-follow-nearest-node fork) (when (save-excursion (search-backward "\n* menu:" nil t)) (save-excursion *************** *** 2223,2257 **** (beginning-of-line 0)) (when (looking-at "\\* +\\([^\t\n]*\\):") (Info-goto-node ! (Info-extract-menu-item (match-string-no-properties 1))) t))) (error "Point neither on reference nor in menu item description"))) ;; Common subroutine. ! (defun Info-try-follow-nearest-node () "Follow a node reference near point. Return non-nil if successful." (let (node) (cond ((setq node (Info-get-token (point) "\\*note[ \n]" "\\*note[ \n]\\([^:]*\\):")) ! (Info-follow-reference node)) ;; menu item: node name ((setq node (Info-get-token (point) "\\* +" "\\* +\\([^:]*\\)::")) ! (Info-goto-node node)) ;; menu item: index entry ((Info-get-token (point) "\\* +" "\\* +\\(.*\\): ") (beginning-of-line) (forward-char 2) (setq node (Info-extract-menu-node-name)) ! (Info-goto-node node)) ((setq node (Info-get-token (point) "Up: " "Up: \\([^,\n\t]*\\)")) ! (Info-goto-node node)) ((setq node (Info-get-token (point) "Next: " "Next: \\([^,\n\t]*\\)")) ! (Info-goto-node node)) ((setq node (Info-get-token (point) "File: " "File: \\([^,\n\t]*\\)")) ! (Info-goto-node "Top")) ((setq node (Info-get-token (point) "Prev: " "Prev: \\([^,\n\t]*\\)")) ! (Info-goto-node node))) node)) (defvar Info-mode-map nil --- 2322,2363 ---- (beginning-of-line 0)) (when (looking-at "\\* +\\([^\t\n]*\\):") (Info-goto-node ! (Info-extract-menu-item (match-string-no-properties 1)) fork) t))) (error "Point neither on reference nor in menu item description"))) ;; Common subroutine. ! (defun Info-try-follow-nearest-node (&optional fork) "Follow a node reference near point. Return non-nil if successful." (let (node) (cond + ((and (Info-get-token (point) "http://" "\\(http://\\)") + (or (featurep 'browse-url) (require 'browse-url nil t))) + (setq node t) + (browse-url (browse-url-url-at-point))) ((setq node (Info-get-token (point) "\\*note[ \n]" "\\*note[ \n]\\([^:]*\\):")) ! (setq Info-reference-name (replace-regexp-in-string ! "[ \t\n]+" " " (match-string-no-properties 1))) ! (Info-follow-reference node fork)) ;; menu item: node name ((setq node (Info-get-token (point) "\\* +" "\\* +\\([^:]*\\)::")) ! (Info-goto-node node fork)) ;; menu item: index entry ((Info-get-token (point) "\\* +" "\\* +\\(.*\\): ") + (setq Info-reference-name (match-string-no-properties 1)) (beginning-of-line) (forward-char 2) (setq node (Info-extract-menu-node-name)) ! (Info-goto-node node fork)) ((setq node (Info-get-token (point) "Up: " "Up: \\([^,\n\t]*\\)")) ! (Info-goto-node node fork)) ((setq node (Info-get-token (point) "Next: " "Next: \\([^,\n\t]*\\)")) ! (Info-goto-node node fork)) ((setq node (Info-get-token (point) "File: " "File: \\([^,\n\t]*\\)")) ! (Info-goto-node "Top" fork)) ((setq node (Info-get-token (point) "Prev: " "Prev: \\([^,\n\t]*\\)")) ! (Info-goto-node node fork))) node)) (defvar Info-mode-map nil *************** *** 2295,2306 **** (define-key Info-mode-map "p" 'Info-prev) (define-key Info-mode-map "q" 'Info-exit) (define-key Info-mode-map "s" 'Info-search) ! ;; For consistency with Rmail. ! (define-key Info-mode-map "\M-s" 'Info-search) (define-key Info-mode-map "\M-n" 'clone-buffer) (define-key Info-mode-map "t" 'Info-top-node) (define-key Info-mode-map "u" 'Info-up) (define-key Info-mode-map "," 'Info-index-next) (define-key Info-mode-map "\177" 'Info-scroll-down) (define-key Info-mode-map [mouse-2] 'Info-mouse-follow-nearest-node) ) --- 2401,2412 ---- (define-key Info-mode-map "p" 'Info-prev) (define-key Info-mode-map "q" 'Info-exit) (define-key Info-mode-map "s" 'Info-search) ! (define-key Info-mode-map "\M-s" 'Info-search-next) (define-key Info-mode-map "\M-n" 'clone-buffer) (define-key Info-mode-map "t" 'Info-top-node) (define-key Info-mode-map "u" 'Info-up) (define-key Info-mode-map "," 'Info-index-next) + (define-key Info-mode-map "\\" 'Info-history-buffer) (define-key Info-mode-map "\177" 'Info-scroll-down) (define-key Info-mode-map [mouse-2] 'Info-mouse-follow-nearest-node) ) *************** *** 2335,2344 **** ("Reference" ["You should never see this" report-emacs-bug t]) ["Search..." Info-search :help "Search for regular expression in this Info file"] ["Go to Node..." Info-goto-node :help "Go to a named node"] ! ["Last" Info-last :active Info-history :help "Go to the last node you were at"] ("Index..." ["Lookup a String" Info-index :help "Look for a string in the index items"] --- 2441,2454 ---- ("Reference" ["You should never see this" report-emacs-bug t]) ["Search..." Info-search :help "Search for regular expression in this Info file"] + ["Search Next" Info-search-next + :help "Search for another occurrence of regular expression"] ["Go to Node..." Info-goto-node :help "Go to a named node"] ! ["Last (Back)" Info-last :active Info-history :help "Go to the last node you were at"] + ["History" Info-history-buffer :active Info-history-tree + :help "Go to the history buffer"] ("Index..." ["Lookup a String" Info-index :help "Look for a string in the index items"] *************** *** 2476,2481 **** --- 2586,2592 ---- \\[Info-directory] Go to the Info directory node. \\[Info-follow-reference] Follow a cross reference. Reads name of reference. \\[Info-last] Move to the last node you were at. + \\[Info-history-buffer] Go to the history buffer. \\[Info-index] Look up a topic in this file's Index and move to that node. \\[Info-index-next] (comma) Move to the next match from a previous `i' command. \\[Info-top-node] Go to the Top node of this file. *************** *** 2504,2509 **** --- 2615,2622 ---- \\[universal-argument] \\[info] Move to new Info file with completion. \\[Info-search] Search through this Info file for specified regexp, and select the node in which the next occurrence is found. + \\[Info-search-next] Search for another occurrence of regexp + from a previous `Info-search' command. \\[Info-next-reference] Move cursor to next cross-reference or menu item. \\[Info-prev-reference] Move cursor to previous cross-reference or menu item." (kill-all-local-variables) *************** *** 2524,2529 **** --- 2637,2643 ---- (make-local-variable 'Info-tag-table-buffer) (setq Info-tag-table-buffer nil) (make-local-variable 'Info-history) + (make-local-variable 'Info-history-node) (make-local-variable 'Info-index-alternatives) (setq header-line-format (if Info-use-header-line *************** *** 2833,2841 **** "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. ! (unless (let ((where (next-property-change (point-min)))) ! (and where (not (= where (point-max))))) (save-excursion (let ((inhibit-read-only t) (case-fold-search t) --- 2947,2957 ---- "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 ! ;; or always fontify visited nodes (because of their dynamic nature). ! (when (or Info-visited-nodes ! (not (let ((where (next-property-change (point-min)))) ! (and where (not (= where (point-max))))))) (save-excursion (let ((inhibit-read-only t) (case-fold-search t) *************** *** 2911,2961 **** (add-text-properties (1- (match-beginning 2)) (match-end 2) '(invisible t front-sticky nil rear-nonsticky t)))) (goto-char (point-min)) ! (while (re-search-forward "\\(\\*Note[ \t]*\\)\n?[ \t]*\\([^:]*\\)\\(:[^.,:(]*\\(([^)]*)[^.,:]*\\)?[,:]?\n?\\)" nil t) ! (unless (= (char-after (1- (match-beginning 0))) ?\") ; hack (let ((start (match-beginning 0)) ! (next (point)) ! (hide-tag Info-hide-note-references) ! other-tag) ! (when hide-tag ! ;; *Note is often used where *note should have been ! (goto-char start) ! (skip-syntax-backward " ") ! (setq other-tag ! (cond ((memq (char-before) '(nil ?\. ?! ??)) ! "See ") ! ((memq (char-before) '(?\, ?\; ?\: ?-)) ! "see ") ! ((memq (char-before) '(?\( ?\[ ?\{)) ! ;; Check whether the paren is preceded by ! ;; an end of sentence ! (skip-syntax-backward " (") ! (if (memq (char-before) '(nil ?\. ?! ??)) ! "See " ! "see ")) ! ((save-match-data (looking-at "\n\n")) ! "See "))) ! (goto-char next)) ! (if hide-tag ! (add-text-properties (match-beginning 1) (match-end 1) ! '(invisible t front-sticky nil rear-nonsticky t))) (add-text-properties (match-beginning 2) (match-end 2) ! (cons 'help-echo ! (cons (if (match-end 4) ! (concat "mouse-2: go to " (match-string 4)) ! "mouse-2: go to this node") ! '(font-lock-face info-xref ! mouse-face highlight)))) (when (eq Info-hide-note-references t) (add-text-properties (match-beginning 3) (match-end 3) ! '(invisible t front-sticky nil rear-nonsticky t))) ! (when other-tag ! (save-excursion ! (goto-char (match-beginning 1)) ! (insert other-tag))) ! (when (and Info-refill-paragraphs ! (or hide-tag (eq Info-hide-note-references t))) (push (set-marker (make-marker) start) paragraph-markers))))) --- 3027,3101 ---- (add-text-properties (1- (match-beginning 2)) (match-end 2) '(invisible t front-sticky nil rear-nonsticky t)))) (goto-char (point-min)) ! (while (re-search-forward "\\(\\*Note[ \t]*\\)\n?[ \t]*\\([^:]*\\)\\(:[^.,:(]*\\((\\([^)]*\\))\\([^.,:]*\\)\\)?[,:]?\n?\\)" nil t) ! (unless (memq (char-after (1- (match-beginning 0))) '(?\" ?\`)) ; hack (let ((start (match-beginning 0)) ! ;; (next (point)) ! ;; other-tag ! ) ! (when Info-hide-note-references ! ;; ;; *Note is often used where *note should have been ! ;; (goto-char start) ! ;; (skip-syntax-backward " ") ! ;; (setq other-tag ! ;; (cond ((memq (char-before) '(nil ?\. ?! ??)) ! ;; "See ") ! ;; ((memq (char-before) '(?\, ?\; ?\: ?-)) ! ;; "see ") ! ;; ((memq (char-before) '(?\( ?\[ ?\{)) ! ;; ;; Check whether the paren is preceded by ! ;; ;; an end of sentence ! ;; (skip-syntax-backward " (") ! ;; (if (memq (char-before) '(nil ?\. ?! ??)) ! ;; "See " ! ;; "see ")) ! ;; ((save-match-data (looking-at "\n\n")) ! ;; "See "))) ! ;; (goto-char next) ! (add-text-properties (match-beginning 1) (match-end 1) ! '(invisible t front-sticky nil rear-nonsticky t))) (add-text-properties (match-beginning 2) (match-end 2) ! (list ! 'help-echo (if (match-end 4) ! (concat "mouse-2: go to " (match-string 4)) ! "mouse-2: go to this node") ! 'font-lock-face ! ;; Display visited nodes in a different face ! (if (and Info-visited-nodes ! (save-match-data ! (let* ((file (concat (or (match-string 5) Info-current-file) "$")) ! (node (replace-regexp-in-string ! "[ \t\n]+" " " ! (or (match-string 6) (match-string 2)))) ! (l Info-history-tree) ! res) ! (while l ! (if (and (equal (cadr (car l)) node) ! (string-match file (caar l))) ! (setq res (car l) l nil)) ! (setq l (cdr l))) ! res))) 'info-xref-visited 'info-xref) ! 'mouse-face 'highlight)) (when (eq Info-hide-note-references t) (add-text-properties (match-beginning 3) (match-end 3) ! '(invisible t front-sticky nil rear-nonsticky t)) ! ;; Unhide the file name of the reference in parens ! (if (match-string 5) ! (remove-text-properties (1- (match-beginning 5)) (1+ (match-end 5)) ! '(invisible t front-sticky nil rear-nonsticky t))) ! ;; Unhide newline because hidden newlines cause too long lines ! (save-match-data ! (let ((start3 (match-beginning 3))) ! (if (string-match "\n[ \t]*" (match-string 3)) ! (remove-text-properties (+ start3 (match-beginning 0)) (+ start3 (match-end 0)) ! '(invisible t front-sticky nil rear-nonsticky t))))) ! ) ! ;; (when other-tag ! ;; (save-excursion ! ;; (goto-char (match-beginning 1)) ! ;; (insert other-tag))) ! (when (and Info-refill-paragraphs Info-hide-note-references) (push (set-marker (make-marker) start) paragraph-markers))))) *************** *** 2997,3009 **** 'font-lock-face 'info-menu-5)) (add-text-properties (match-beginning 1) (match-end 1) ! (cons 'help-echo ! (cons ! (if (match-end 3) ! (concat "mouse-2: go to " (match-string 3)) ! "mouse-2: go to this node") ! '(font-lock-face info-xref ! mouse-face highlight)))) (when (eq Info-hide-note-references t) (put-text-property (match-beginning 2) (1- (match-end 6)) 'invisible t) --- 3137,3161 ---- 'font-lock-face 'info-menu-5)) (add-text-properties (match-beginning 1) (match-end 1) ! (list ! 'help-echo (if (match-end 3) ! (concat "mouse-2: go to " (match-string 3)) ! "mouse-2: go to this node") ! 'font-lock-face ! ;; Display visited nodes in a different face ! (if (and Info-visited-nodes ! (let ((node (if (equal (match-string 3) "") ! (match-string 1) ! (match-string 3))) ! (l Info-history-tree) ! res) ! (while l ! (if (and (equal (cadr (car l)) node) ! (equal Info-current-file (caar l))) ! (setq res (car l) l nil)) ! (setq l (cdr l))) ! res)) 'info-xref-visited 'info-xref) ! 'mouse-face 'highlight)) (when (eq Info-hide-note-references t) (put-text-property (match-beginning 2) (1- (match-end 6)) 'invisible t) *************** *** 3026,3031 **** --- 3178,3190 ---- '(space :align-to 24))) (setq cont t)))))) + (goto-char (point-min)) + (while (re-search-forward "http://[-~/[:alnum:]_.${}#%,:?=&]+" nil t) + (add-text-properties (match-beginning 0) (match-end 0) + '(font-lock-face info-xref + mouse-face highlight + help-echo "mouse-2: go to this URL"))) + (Info-fontify-menu-headers) (set-buffer-modified-p nil))))) =================================================================== -- http://www.jurta.org/emacs/