emacs-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Info enhancements


From: Juri Linkov
Subject: Re: Info enhancements
Date: Fri, 12 Dec 2003 04:08:56 +0200
User-agent: Gnus/5.1003 (Gnus v5.10.3) Emacs/21.3.50 (gnu/linux)

I'd like to submit the new version of a patch that fixes problems
in the Emacs Info reader and adds new features.  Actually, this is a
patch to the previous patch because below I describe the changes made
after previous changes.  I can send a full patch when needed.
Thanks for all the responses to the previous patch.

* Implemented a new `S' command suggested by Eli.  This command is
  bound to a new function `Info-search-case-sensitively' that searches
  for a regexp case-sensitively.  The `Info-search-next' uses the case
  of a previous `Info-search' or `Info-search-case-sensitively' command.

* Added a new keybinding "/" for `Info-search-next' (suggested by Reiner).

* Added a new variable `Info-search-whitespace-regexp' used to match a
  sequence of whitespace chars in Info search.  I borrowed this idea
  from `search-whitespace-regexp' from isearch.el.

* Removed the history tree feature from the previous patch because
  I found that history tree is less useful than a history list.  There
  are many different variants of tree creation so I couldn't decide
  which is the better one.  But I think that a plain history list
  sorted by node visiting order is good enough.  The history list
  items are represented now by menu instead of references because menu
  is more useful for selecting history nodes (keys 1-9 can be used to
  quickly select a history item in node's menu).

* Unhide a file name in menu items if it has no period after parentheses,
  (i.e. it don't refer to the "Top" node).  This is needed mostly
  for the history list menu where Info file names should be shown.

* Node Tree: this new feature generates a separate buffer with a tree
  of all Info node names collected from an Info file.  The node-subnode
  relationships are extracted from node menus.  The generated buffer
  with a node tree contains the references to Info nodes.  I "stole"
  two functions for this feature from ee-info.el file that builds
  different tree views of Info nodes.  I think that node tree feature
  will be useful even for users not installed the Ee package.  The
  keybinding for this feature is "*".

* A new value 'hide ("Hide tag and reference") of user variable
  `Info-hide-note-references' is added for users that don't want
  to see "see" (no pun intended almost) instead of "*note".  This
  option is also needed for the node tree feature because inserting
  "see" before every node in a node tree is too ugly.

* The function `Info-follow-reference' gives the preference to the
  reference at or closest to point (suggested by Eli to make it
  similar to the standalone Info reader).  However, currently it
  don't handle a situation with off-screen references, because it's
  too impractical to write code for such extremely rare situations.

* The functions `Info-next-reference' and `Info-prev-reference' now
  skip the "*note" tag and move cursor to the position on reference
  immediately after this tag.  This is especially useful when "*note"
  is replaced with "see" by a `display' property as suggested by Kim
  because it's better when point is placed directly on the reference
  instead of the "see" text.

* The command `u' (`Info-up') now relocates point to the menu item
  with the name of a previously visited node.  Very useful to keep
  track of node navigation from menu.

* All anchors are filtered out from a node completion list.  I'm not
  sure whether a separate command with anchor list to select and go to
  a selected anchor by its name is needed or not?  Seems anchors are
  useful only for making references to them, not for selecting them
  from completion list.

* Fixed a bug reported by Luc for the previous patch where anchors
  were disabled by the reference names feature.  I still think this
  feature is very useful especially for moving from indexes directly
  to lines where index items are described.  This feature can be
  replaced later gradually by anchors as suggested by Luc.  However,
  now this feature needs more testing to collect more evidences for
  its usefulness/uselessness/harmfulness.

* Fixed a bug reported by Luc where header-line's gone blank.
  It's fixed by calling fontification only once, but calling
  refontification of visited links every time.

* The function `Info-fontify-menu-headers' is removed and its content
  moved to `Info-fontify-node' where is was called before.

===================================================================
diff -cwB emacs/lisp/info.el~ emacs/lisp/info.el
*** emacs/lisp/info.el~ Tue Dec 02 00:25:29 2003
--- emacs/lisp/info.el  Fri Dec 12 02:45:12 2003
***************
*** 45,59 ****
  
  
  (defvar Info-history nil
!   "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-mode-map>\\[Info-edit] command in Info can edit 
the current node.
--- 45,56 ----
  
  
  (defvar Info-history nil
!   "Stack of info nodes user has visited.
  Each element of list is a list (FILENAME NODENAME BUFFERPOS).")
  
! (defvar Info-history-list nil
!   "Full list of all info nodes user has ever visited.
! Each element of list is a list (FILENAME NODENAME).")
  
  (defcustom Info-enable-edit nil
    "*Non-nil means the \\<Info-mode-map>\\[Info-edit] command in Info can edit 
the current node.
***************
*** 175,185 ****
  
  (defcustom Info-hide-note-references t
    "*If non-nil, hide the tag and section reference in *note and * menu items.
  If value is non-nil but not t, the reference section is still shown."
    :version "21.4"
!   :type '(choice (const :tag "No reformatting" nil)
                 (const :tag "Replace tag and hide reference" t)
!                (other :tag "Replace only tag" tag))
    :group 'info)
  
  (defcustom Info-refill-paragraphs nil
--- 172,184 ----
  
  (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 hiding" nil)
                 (const :tag "Replace tag and hide reference" t)
!                (other :tag "Hide tag and reference" hide)
!                (other :tag "Only replace tag" tag))
    :group 'info)
  
  (defcustom Info-refill-paragraphs nil
***************
*** 190,195 ****
--- 189,203 ----
    :type 'boolean
    :group 'info)
  
+ (defcustom Info-search-whitespace-regexp "\\\\(?:\\\\s-+\\\\)"
+   "*If non-nil, regular expression to match a sequence of whitespace chars.
+ This applies to regular expression Info search.
+ You might want to use something like \"[ \\t\\r\\n]+\" instead.
+ In the Customization buffer, that is `[' followed by a space,
+ a tab, a carriage return (control-M), a newline, and `]+'."
+   :type 'regexp
+   :group 'info)
+ 
  (defcustom Info-mode-hook
    ;; Try to obey obsolete Info-fontify settings.
    (unless (and (boundp 'Info-fontify) (null Info-fontify))
***************
*** 225,231 ****
    "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.")
--- 233,241 ----
    "List of possible matches for last `Info-index' command.")
  
  (defvar Info-reference-name nil
!   "Name of the selected cross-reference.
! Point is moved to the proper occurrence of this name within a node
! after selecting it.")
  
  (defvar Info-standalone nil
    "Non-nil if Emacs was started solely as an Info browser.")
***************
*** 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)
--- 819,829 ----
                       nodename)))
  
            (Info-select-node)
!           (goto-char (point-min))
!           (cond (anchorpos (goto-char anchorpos))
!                 (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)
***************
*** 1201,1225 ****
                                            (read (current-buffer))))))
                            (point-max)))
        (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 ()
--- 1210,1221 ----
                                            (read (current-buffer))))))
                            (point-max)))
        (if Info-enable-active-nodes (eval active-expression))
+       ;; Add a new unique history item to full history list
+       (let ((new-history (list Info-current-file Info-current-node)))
+         (setq Info-history-list
+               (cons new-history (delete new-history Info-history-list))))
        (Info-fontify-node)
        (Info-display-images-node)
        (run-hooks 'Info-selection-hook)))))
  
  (defun Info-set-mode-line ()
***************
*** 1251,1257 ****
    (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 *\\|\\)\\(.*\\)"
--- 1247,1253 ----
    (if fork
        (set-buffer
         (clone-buffer (concat "*info-" (if (stringp fork) fork nodename) "*") 
t)))
!   (if (member (buffer-name) '("*info-history*" "*info-tree*"))
        (switch-to-buffer "*info*"))
    (let (filename)
      (string-match "\\s *\\((\\s *\\([^\t)]*\\)\\s *)\\s *\\|\\)\\(.*\\)"
***************
*** 1327,1335 ****
                  (widen)
                  (goto-char marker)
                  (while (re-search-forward "\n\\(Node\\|Ref\\): \\(.*\\)\177" 
nil t)
                    (setq compl
                          (cons (list (match-string-no-properties 2))
!                               compl))))
              (widen)
              (goto-char (point-min))
              ;; If the buffer begins with a node header, process that first.
--- 1323,1332 ----
                  (widen)
                  (goto-char marker)
                  (while (re-search-forward "\n\\(Node\\|Ref\\): \\(.*\\)\177" 
nil t)
+                   (or (string-equal "Ref" (match-string 1))
                        (setq compl
                              (cons (list (match-string-no-properties 2))
!                                   compl)))))
              (widen)
              (goto-char (point-min))
              ;; If the buffer begins with a node header, process that first.
***************
*** 1361,1366 ****
--- 1358,1366 ----
  (defvar Info-search-history nil
    "The history list for `Info-search'.")
  
+ (defvar Info-search-case-fold nil
+   "The value of `case-fold-search' from previous `Info-search' command.")
+ 
  (defun Info-search (regexp)
    "Search for REGEXP, starting from point, and select node it's found in."
    (interactive (list (read-string
***************
*** 1380,1385 ****
--- 1380,1389 ----
          (opoint (point))
          (ostart (window-start))
          (osubfile Info-current-subfile))
+       (when Info-search-whitespace-regexp
+         (setq regexp (replace-regexp-in-string
+                       "[ \t\n]+" Info-search-whitespace-regexp regexp)))
+       (setq Info-search-case-fold case-fold-search)
        (save-excursion
        (save-restriction
          (widen)
***************
*** 1456,1468 ****
          (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.
--- 1460,1478 ----
          (setq Info-history (cons (list ofile onode opoint)
                                   Info-history))))))
  
+ (defun Info-search-case-sensitively ()
+   "Search for a regexp case-sensitively."
+   (interactive)
+   (let ((case-fold-search nil))
+     (call-interactively 'Info-search)))
+ 
  (defun Info-search-next ()
    "Search for next regexp from a previous `Info-search' command."
    (interactive)
+   (let ((case-fold-search Info-search-case-fold))
      (if Info-search-history
          (Info-search (car Info-search-history))
!       (call-interactively 'Info-search))))
  
  (defun Info-extract-pointer (name &optional errorname)
    "Extract the value of the node-pointer named NAME.
***************
*** 1514,1525 ****
    "Go to the superior node of this node.
  If SAME-FILE is non-nil, do not move to a different Info file."
    (interactive)
!   (let ((node (Info-extract-pointer "up")))
      (and (or same-file (not (stringp Info-current-file)))
         (string-match "^(" node)
         (error "Up node is in another Info file"))
!     (Info-goto-node node))
!   (Info-restore-point Info-history))
  
  (defun Info-last ()
    "Go back to the last node visited."
--- 1524,1547 ----
    "Go to the superior node of this node.
  If SAME-FILE is non-nil, do not move to a different Info file."
    (interactive)
!   (let ((old-node Info-current-node)
!         (old-file Info-current-file)
!         (node (Info-extract-pointer "up")) p)
      (and (or same-file (not (stringp Info-current-file)))
         (string-match "^(" node)
         (error "Up node is in another Info file"))
!     (Info-goto-node node)
!     (setq p (point))
!     (goto-char (point-min))
!     (if (and (search-forward "\n* Menu:" nil t)
!              (re-search-forward
!               (if (string-equal old-node "Top")
!                   (concat "\n\\*.+: (" (file-name-nondirectory old-file) ")")
!                 (concat "\n\\* +" old-node ":"))
!               nil t))
!         (beginning-of-line)
!       (goto-char p)
!       (Info-restore-point Info-history))))
  
  (defun Info-last ()
    "Go back to the last node visited."
***************
*** 1535,1587 ****
      (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.
--- 1557,1758 ----
      (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"))
+ 
  ;;;###autoload (add-hook 'same-window-buffer-names "*info-history*")
  
! (defun Info-history-buffer ()
!   "Create the buffer *info-history* with references to visited nodes."
!   (interactive)
!   (let ((curr-file Info-current-file)
!         (curr-node Info-current-node)
          p)
      (pop-to-buffer
       (with-current-buffer (get-buffer-create "*info-history*")
!        (let ((inhibit-read-only t))
           (erase-buffer)
           (goto-char (point-min))
!          (insert "Node: History\n\n* Menu:\n\n")
!          (let ((hl Info-history-list))
!            (while hl
!              (let ((file (nth 0 (car hl)))
!                    (node (nth 1 (car hl))))
!                (if (and (equal file curr-file)
!                         (string-equal node curr-node))
!                    (setq p (point)))
!                (insert "* " node ": (" (file-name-nondirectory file)
!                        ")" node ".\n"))
!              (setq hl (cdr hl))))
           (or (eq major-mode 'Info-mode) (Info-mode))
!          (setq Info-current-file "info-history")
!          (setq Info-current-node "Info History")
!          (Info-set-mode-line)
!          (if (not (bobp)) (Info-fontify-node))
           (current-buffer))))
      (goto-char (or p (point-min)))))
  
! ;;;###autoload (add-hook 'same-window-buffer-names "*info-tree*")
  
! (defun Info-node-tree-buffer ()
!   "Create the buffer *info-tree* with Info node tree."
    (interactive)
!   (let ((curr-file Info-current-file)
!         (curr-node Info-current-node)
!         p)
!     (pop-to-buffer
!      (with-current-buffer (get-buffer-create "*info-tree*")
!        (if (not (equal Info-current-file curr-file))
!            (let ((inhibit-read-only t)
!                  (node-list (Info-node-tree-collect-menus curr-file)))
!              (erase-buffer)
!              (goto-char (point-min))
!              (insert "Node: Node Tree\n\n")
!              (Info-node-tree-insert
!               (delq nil (mapcar (lambda (node)
!                                   (if (nth 1 node)
!                                       (nth 0 node))) node-list))
!               node-list 0)
!              (set (make-local-variable 'Info-current-file) curr-file)
!              (or (eq major-mode 'Info-mode) (Info-mode))
!              (setq Info-current-node "Info Node Tree")
!              (Info-set-mode-line)))
!        (if (not (bobp))
!            (let ((Info-hide-note-references 'hide))
!              (Info-fontify-node)))
!        (goto-char (point-min))
!        (if (setq p (search-forward (concat "*Note " curr-node "::") nil t))
!            (setq p (- p (length curr-node) 8)))       (current-buffer)))
!     (goto-char (or p (point-min)))))
! 
! (defun Info-node-tree-insert (nodes node-list level)
!   "Insert the node tree of references to nodes."
!   (while nodes
!     (insert (make-string (* level 4) ?\040))
!     (insert "*Note " (car nodes) "::\n")
!     (Info-node-tree-insert (nth 2 (assoc (car nodes) node-list))
!                            node-list
!                            (1+ level))
!     (setq nodes (cdr nodes))))
! 
! (defvar Info-node-tree-section-names nil
!   "Global variable to hold association list during data collection.
! The elements of list are (\"section name\" . \"node name\").")
! 
! (defun Info-node-tree-collect-menus (filename)
!   "Collect all node names and subnodes from current Info file."
!   (save-excursion
!     (let ((res))
!       (set-buffer (get-buffer-create " *info-node-tree*"))
!       (or (eq major-mode 'Info-mode) (Info-mode))
!       (Info-find-node filename "Top")
!       (setq Info-node-tree-section-names '(("Top" "Top")))
!       ;; Read menus from info file of Top node
!       ;; (setq res (Info-node-tree-collect-menus-current))
!       ;; Read menus from info subfiles
!       (let ((list ())
!             (osubfile ))
!         ;; Get list of subfiles (code borrowed from `Info-search')
!         (save-excursion
!           (set-buffer (marker-buffer Info-tag-table-marker))
!           (goto-char (point-min))
!           (if (search-forward "\n\^_\nIndirect:" nil t)
!               (save-restriction
!                 (narrow-to-region (point)
!                                   (progn (search-forward "\n\^_")
!                                          (1- (point))))
!                 (goto-char (point-min))
!                 (beginning-of-line)
!                 (while (not (eobp))
!                   (re-search-forward "\\(^.*\\): [0-9]+$")
!                   (goto-char (+ (match-end 1) 2))
!                   (setq list (cons (cons (read (current-buffer))
!                                          (buffer-substring-no-properties
!                                           (match-beginning 1) (match-end 1)))
!                                    list))
!                   (goto-char (1+ (match-end 0))))
!                 (setq list (nreverse list)
!                       list (cdr list)))))
!         (while list
!           (message "Searching subfile %s..." (cdr (car list)))
!           (Info-read-subfile (car (car list)))
!           (setq res (append (Info-node-tree-collect-menus-current) res))
!           (setq list (cdr list)))
!         (nreverse res)))))
! 
! (defun Info-node-tree-collect-menus-current ()
!   "Return list of menus extracted from current Info file.
! Return all nodes, even those that are not accessible from menus.
! Output: ((\"nodename1\",\"sectname1\",(\"subnode2\",\"subnode3\")))."
!   (let ((res))
!     (save-excursion
!       (save-restriction
!         (widen)
!         (goto-char (point-min))
!         (while (and (search-forward "\n\^_\nFile:" nil 'move)
!                     (search-forward "Node: " nil 'move))
!           (let (nodename section-name menu-items index-items ref-items beg 
bound)
!             (setq nodename (substring-no-properties 
(Info-following-node-name)))
!             (forward-line 1)
!             (setq beg (point))
!             (search-forward "\n\^_" nil 'move)
!             (beginning-of-line)
!             (forward-line -1)
!             (setq bound (point))
!             (goto-char beg)
!             (when (re-search-forward "^\\* Menu:" bound t)
!               (forward-line 1)
!               (beginning-of-line)
!               (cond
!                ((equal nodename "Top")
!                 (while (and (< (point) bound)
!                             (not (looking-at "^[ \t]*-+ The Detailed Node 
Listing")))
!                   (cond
!                    ;; Menu line
!                    ((looking-at "^\\* +\\([^:\t\n]*\\):")
!                     (beginning-of-line)
!                     (forward-char 2)
!                     (let ((menu-node-name (substring-no-properties 
(Info-extract-menu-node-name))))
!                       (setq menu-items
!                             (cons menu-node-name ;; (list menu-node-name 
section-name)
!                                   ;; (match-string-no-properties 1)
!                                   menu-items))
!                       (setq Info-node-tree-section-names
!                             (cons (list menu-node-name (or section-name 
"Top"))
!                                    Info-node-tree-section-names))))
!                    ;; Other non-empty strings in the dir buffer are section 
names
!                    ((looking-at "^\\([^ \t\n][^:\n]*\\)")
!                     (setq section-name (match-string-no-properties 1))))
!                   (forward-line 1)
!                   (beginning-of-line)))
!                ((string-match "Index" nodename)
!                 ;; Accept index menu items, e.g.:
!                 ;; * forward-list:                          List Motion.
!                 (while (re-search-forward "\n\\* +\\([^:\t\n]*\\):" bound t)
!                   (beginning-of-line)
!                   (forward-char 2)
!                   (setq index-items (cons (substring-no-properties 
(Info-extract-menu-node-name))
!                                           ;; (match-string-no-properties 1)
!                                           index-items))))
!                (t
!                 (while (re-search-forward "\n\\* +\\([^:\t\n]*\\):" bound t)
!                   (beginning-of-line)
!                   (forward-char 2)
!                   (setq menu-items (cons (substring-no-properties 
(Info-extract-menu-node-name))
!                                          ;; (match-string-no-properties 1)
!                                          menu-items))))))
!             (setq res (cons (list nodename
!                                   (cadr (assoc nodename 
Info-node-tree-section-names))
!                                   (if (not (equal nodename "Top")) ; hack
!                                       (nreverse menu-items))
!                                   (nreverse index-items))
!                             res))
!             (goto-char bound)))))
!     res))
  
  (defun Info-follow-reference (footnotename &optional fork)
    "Follow cross reference named FOOTNOTENAME to the node it refers to.
***************
*** 1650,1661 ****
        (setq str (concat (substring str 0 i) "[ \t\n]+" (substring str (1+ 
i))))
        (setq i (+ i 6)))
      (save-excursion
!       (goto-char (point-min))
!       (or (re-search-forward str nil t)
!         (error "No cross-reference named %s" footnotename))
!       (goto-char (+ (match-beginning 0) 5))
!       (setq target
!           (Info-extract-menu-node-name t)))
      (while (setq i (string-match "[ \t\n]+" target i))
        (setq target (concat (substring target 0 i) " "
                           (substring target (match-end 0))))
--- 1821,1848 ----
        (setq str (concat (substring str 0 i) "[ \t\n]+" (substring str (1+ 
i))))
        (setq i (+ i 6)))
      (save-excursion
!       ;; Move point to the beginning of reference if point is on reference
!       (or (looking-at "\\*note[ \n\t]*")
!           (and (looking-back "\\*note[ \n\t]*")
!                (goto-char (match-beginning 0)))
!           (if (and (save-excursion
!                      (goto-char (+ (point) 5)) ; skip a possible *note
!                      (search-backward "\*note " nil t)
!                      (looking-at (concat "\\*note " 
(Info-following-node-name-re))))
!                    (<= (point) (match-end 0)))
!               (goto-char (match-beginning 0))))
!       ;; Go to the reference closest to point
!       (let ((next-ref (save-excursion (and (re-search-forward str nil t)
!                                            (+ (match-beginning 0) 5))))
!             (prev-ref (save-excursion (and (re-search-backward str nil t)
!                                            (+ (match-beginning 0) 5)))))
!         (goto-char (cond ((and next-ref prev-ref)
!                           (if (< (abs (- next-ref (point)))
!                                  (abs (- prev-ref (point))))
!                               next-ref prev-ref))
!                          ((or next-ref prev-ref))
!                          ((error "No cross-reference named %s" 
footnotename))))
!         (setq target (Info-extract-menu-node-name t))))
      (while (setq i (string-match "[ \t\n]+" target i))
        (setq target (concat (substring target 0 i) " "
                           (substring target (match-end 0))))
***************
*** 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))
--- 2254,2260 ----
  (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]*\\([^:]*\\):\\|^\\* .*:\\|[hf]t?tp://")
        (old-pt (point))
        (case-fold-search t))
      (or (eobp) (forward-char 1))
***************
*** 2079,2084 ****
--- 2266,2273 ----
                (goto-char old-pt)
                (error "No cross references in this node")))))
      (goto-char (match-beginning 0))
+     (if (looking-at "\\*note[ \n\t]*")
+         (forward-char (- (match-end 0) (match-beginning 0))))
      (if (looking-at "\\* Menu:")
        (if recur
            (error "No cross references in this node")
***************
*** 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)
--- 2276,2282 ----
  (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]*\\([^:]*\\):\\|^\\* .*:\\|[hf]t?tp://")
        (old-pt (point))
        (case-fold-search t))
      (or (re-search-backward pat nil t)
***************
*** 2098,2103 ****
--- 2287,2294 ----
                (goto-char old-pt)
                (error "No cross references in this node")))))
      (goto-char (match-beginning 0))
+     (if (looking-at "\\*note[ \n\t]*")
+         (forward-char (- (match-end 0) (match-beginning 0))))
      (if (looking-at "\\* Menu:")
        (if recur
            (error "No cross references in this node")
***************
*** 2331,2337 ****
    "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)))
--- 2522,2528 ----
    "Follow a node reference near point.  Return non-nil if successful."
    (let (node)
      (cond
!      ((and (Info-get-token (point) "[hf]t?tp://" "[hf]t?tp://\\([^ 
\t\n\"`({<>})']+\\)")
             (or (featurep 'browse-url) (require 'browse-url nil t)))
        (setq node t)
        (browse-url (browse-url-url-at-point)))
***************
*** 2345,2351 ****
        (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))
--- 2536,2543 ----
        (Info-goto-node node fork))
       ;; menu item: index entry
       ((Info-get-token (point) "\\* +" "\\* +\\(.*\\): ")
!       (or (member Info-current-file '("dir" "info-history"))
!           (setq Info-reference-name (match-string-no-properties 1)))
        (beginning-of-line)
        (forward-char 2)
        (setq node (Info-extract-menu-node-name))
***************
*** 2401,2412 ****
--- 2593,2607 ----
    (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 "S" 'Info-search-case-sensitively)
+   (define-key Info-mode-map "/" 'Info-search-next)
    (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 "*" 'Info-node-tree-buffer)
    (define-key Info-mode-map "\177" 'Info-scroll-down)
    (define-key Info-mode-map [mouse-2] 'Info-mouse-follow-nearest-node)
    )
***************
*** 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"]
--- 2636,2653 ----
     ("Reference" ["You should never see this" report-emacs-bug t])
     ["Search..." Info-search
      :help "Search for regular expression in this Info file"]
+    ["Search Case-Sensitively..." Info-search-case-sensitively
+     :help "Search for regular expression case sensitively"]
     ["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-list
      :help "Go to the history buffer"]
+    ["Node Tree" Info-node-tree-buffer
+     :help "Go to the node tree buffer"]
     ("Index..."
      ["Lookup a String" Info-index
       :help "Look for a string in the index items"]
***************
*** 2587,2592 ****
--- 2786,2792 ----
  \\[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-node-tree-buffer]     Go to the node tree 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.
***************
*** 2615,2620 ****
--- 2815,2822 ----
  \\[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-case-sensitively]      Search through this Info file
+         for specified regexp case-sensitively.
  \\[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.
***************
*** 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
--- 2839,2844 ----
***************
*** 2907,2923 ****
        (push (substring string start end) matches)
        (apply #'concat (nreverse matches)))))
  
- (defun Info-fontify-menu-headers ()
-   "Add the face `info-menu-header' to any header before a menu entry."
-   (save-excursion
-     (goto-char (point-min))
-     (when (re-search-forward "^\\* Menu:" nil t)
-       (put-text-property (match-beginning 0) (match-end 0)
-                        'font-lock-face 'info-menu-header)
-       (while (re-search-forward "\n\n\\([^*\n ].*\\)\n\n?[*]" nil t)
-       (put-text-property (match-beginning 1) (match-end 1)
-                          'font-lock-face 'info-menu-header)))))
- 
  (defvar Info-next-link-keymap
    (let ((keymap (make-sparse-keymap)))
      (define-key keymap [header-line mouse-1] 'Info-next)
--- 3108,3113 ----
***************
*** 2947,2963 ****
    "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)
!           paragraph-markers)
        (goto-char (point-min))
!       (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))
--- 3137,3158 ----
    "Keymap to put on the Up link in the text or the header line.")
  
  (defun Info-fontify-node ()
!   "Fontify the node."
    (save-excursion
!     (let* ((inhibit-read-only t)
             (case-fold-search t)
!            paragraph-markers
!            (not-fontified-p ; the node hasn't already been fontified
!             (not (let ((where (next-property-change (point-min))))
!                    (and where (not (= where (point-max)))))))
!            (fontify-visited-p ; visited nodes need to be re-fontified
!             (and Info-visited-nodes
!                  ;; Don't take time to refontify visited nodes in huge nodes
!                  (< (- (point-max) (point-min)) 
Info-fontify-maximum-menu-size))))
! 
!       ;; Fontify header line
        (goto-char (point-min))
!       (when (and not-fontified-p (looking-at "^\\(File: [^,: \t]+,?[ 
\t]+\\)?"))
          (goto-char (match-end 0))
          (while (looking-at "[ \t]*\\([^:, \t\n]+\\):[ \t]+\\([^:,\t\n]+\\),?")
            (goto-char (match-end 0))
***************
*** 3009,3015 ****
--- 3203,3212 ----
                ;; Hide the punctuation at the end, too.
                (skip-chars-backward " \t,")
                (put-text-property (point) header-end 'invisible t)))))
+ 
+       ;; Fontify titles
        (goto-char (point-min))
+       (when not-fontified-p
          (while (re-search-forward "\n\\([^ 
\t\n].+\\)\n\\(\\*+\\|=+\\|-+\\|\\.+\\)$"
                                    nil t)
            (let* ((c (preceding-char))
***************
*** 3025,3105 ****
          ;; on frames that can display the font above.
          (when (memq (framep (selected-frame)) '(x pc w32 mac))
            (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)))))
  
!       (when (and Info-refill-paragraphs
                   paragraph-markers)
          (let ((fill-nobreak-invisible t)
                (fill-individual-varying-indent nil)
--- 3222,3313 ----
            ;; on frames that can display the font above.
            (when (memq (framep (selected-frame)) '(x pc w32 mac))
              (add-text-properties (1- (match-beginning 2)) (match-end 2)
!                                  '(invisible t front-sticky nil 
rear-nonsticky t)))))
! 
!       ;; Fontify cross references
        (goto-char (point-min))
!       (when (or not-fontified-p fontify-visited-p)
!         (while (re-search-forward "\\(\\*Note[ \t]*\\)\n?[ 
\t]*\\([^:]*\\)\\(:[ 
\t]*\\([^.,:(]*\\)\\((\\([^)]*\\))\\([^.,:]*\\)\\)?[,:]?\n?\\)" nil t)
            (unless (memq (char-after (1- (match-beginning 0))) '(?\" ?\`)) ; 
hack
              (let ((start (match-beginning 0))
!                   (next (point))
!                   other-tag)
!               (when not-fontified-p
                  (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)
!                    (if (and other-tag (not (eq Info-hide-note-references 
'hide)))
!                        `(display ,other-tag front-sticky nil rear-nonsticky t)
!                      '(invisible t front-sticky nil rear-nonsticky t))))
                  (add-text-properties
                   (match-beginning 2) (match-end 2)
                   (list
!                   'help-echo (if (or (match-end 5) (not (equal (match-string 
4) "")))
!                                  (concat "mouse-2: go to " (or (match-string 
5) (match-string 4)))
                                 "mouse-2: go to this node")
+                   'mouse-face 'highlight)))
+               (when (or not-fontified-p fontify-visited-p)
+                 (add-text-properties
+                  (match-beginning 2) (match-end 2)
+                  (list
                    'font-lock-face
                    ;; Display visited nodes in a different face
!                   (if (save-match-data
!                         (let* ((file (concat (or (match-string 6)
!                                                  Info-current-file) "$"))
                                 (node (replace-regexp-in-string
                                        "[ \t\n]+" " "
!                                       (or (match-string 7)
!                                           (and (not (equal (match-string 4) 
""))
!                                                (match-string 4))
!                                           (match-string 2))))
!                                (hl Info-history-list)
                                 res)
!                           (while hl
!                             (if (and (string-equal node (nth 1 (car hl)))
!                                      (string-match file (nth 0 (car hl))))
!                                 (setq res (car hl) hl nil))
!                             (setq hl (cdr hl)))
!                           res)) 'info-xref-visited 'info-xref))))
!               (when not-fontified-p
!                 (when (memq Info-hide-note-references '(t hide))
                    (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 6)
!                       (remove-text-properties (1- (match-beginning 6)) (1+ 
(match-end 6))
                                                '(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 (and Info-refill-paragraphs Info-hide-note-references)
                    (push (set-marker (make-marker) start)
!                         paragraph-markers)))))))
  
!       ;; Refill paragraphs (experimental feature)
!       (when (and not-fontified-p
!                  Info-refill-paragraphs
                   paragraph-markers)
          (let ((fill-nobreak-invisible t)
                (fill-individual-varying-indent nil)
***************
*** 3119,3126 ****
                      (goto-char beg))))
                (set-marker m nil)))))
  
        (goto-char (point-min))
!       (when (and (search-forward "\n* Menu:" nil t)
                   (not (string-match "\\<Index\\>" Info-current-node))
                   ;; Don't take time to annotate huge menus
                   (< (- (point-max) (point)) Info-fontify-maximum-menu-size))
--- 3327,3336 ----
                      (goto-char beg))))
                (set-marker m nil)))))
  
+       ;; Fontify menu items
        (goto-char (point-min))
!       (when (and (or not-fontified-p fontify-visited-p)
!                  (search-forward "\n* Menu:" nil t)
                   (not (string-match "\\<Index\\>" Info-current-node))
                   ;; Don't take time to annotate huge menus
                   (< (- (point-max) (point)) Info-fontify-maximum-menu-size))
***************
*** 3130,3164 ****
                    (concat "^\\* +\\(" Info-menu-entry-name-re "\\)\\(:"
                            Info-node-spec-re "\\([ \t]*\\)\\)")
                    nil t)
              (setq n (1+ n))
              (if (and (<= n 9) (zerop (% n 3))) ; visual aids to help with 1-9 
keys
                  (put-text-property (match-beginning 0)
                                     (1+ (match-beginning 0))
!                                    '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)
                ;; We need a stretchable space like :align-to but with
                ;; a minimum value.
                (put-text-property (1- (match-end 6)) (match-end 6) 'display
--- 3340,3388 ----
                    (concat "^\\* +\\(" Info-menu-entry-name-re "\\)\\(:"
                            Info-node-spec-re "\\([ \t]*\\)\\)")
                    nil t)
+             (when not-fontified-p
                (setq n (1+ n))
                (if (and (<= n 9) (zerop (% n 3))) ; visual aids to help with 
1-9 keys
                    (put-text-property (match-beginning 0)
                                       (1+ (match-beginning 0))
!                                      'font-lock-face 'info-menu-5)))
!             (when not-fontified-p
                (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")
+                 'mouse-face 'highlight)))
+             (when (or not-fontified-p fontify-visited-p)
+               (add-text-properties
+                (match-beginning 1) (match-end 1)
+                (list
                  'font-lock-face
!                 ;; Display visited menu items in a different face
!                 (if (save-match-data
                        (let ((node (if (equal (match-string 3) "")
                                        (match-string 1)
                                      (match-string 3)))
!                             (file (concat Info-current-file "$"))
!                             (hl Info-history-list)
                              res)
!                         (if (string-match "(\\([^)]+\\))" node)
!                             (setq file (concat (match-string 1 node) "$")
!                                   node "Top"))
!                         (while hl
!                           (if (and (string-equal node (nth 1 (car hl)))
!                                    (string-match file (nth 0 (car hl))))
!                               (setq res (car hl) hl nil))
!                           (setq hl (cdr hl)))
!                         res)) 'info-xref-visited 'info-xref))))
!             (when (and not-fontified-p (memq Info-hide-note-references '(t 
hide)))
                (put-text-property (match-beginning 2) (1- (match-end 6))
                                   'invisible t)
+               ;; Unhide the file name in parens
+               (if (and (match-end 4) (not (eq (char-after (match-end 4)) ?.)))
+                   (remove-text-properties (match-beginning 4) (match-end 4)
+                                           '(invisible t)))
                ;; We need a stretchable space like :align-to but with
                ;; a minimum value.
                (put-text-property (1- (match-end 6)) (match-end 6) 'display
***************
*** 3178,3192 ****
                                       '(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)))))
  
  
  ;; When an Info buffer is killed, make sure the associated tags buffer
--- 3402,3426 ----
                                       '(space :align-to 24)))
                  (setq cont t))))))
  
+       ;; Add the face `info-xref' to http links
        (goto-char (point-min))
!       (when not-fontified-p
!         (while (re-search-forward "[hf]t?tp://[^ \t\n\"`({<>})']+" 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"))))
! 
!       ;; Add the face `info-menu-header' to any header before a menu entry
!       (goto-char (point-min))
!       (when (and not-fontified-p (re-search-forward "^\\* Menu:" nil t))
!         (put-text-property (match-beginning 0) (match-end 0)
!                            'font-lock-face 'info-menu-header)
!         (while (re-search-forward "\n\n\\([^*\n ].*\\)\n\n?[*]" nil t)
!           (put-text-property (match-beginning 1) (match-end 1)
!                              'font-lock-face 'info-menu-header)))
  
!       (set-buffer-modified-p nil))))
  
  
  ;; When an Info buffer is killed, make sure the associated tags buffer
===================================================================

-- 
http://www.jurta.org/emacs/





reply via email to

[Prev in Thread] Current Thread [Next in Thread]