Subject: Re: bug#5809: 23.1.94; cross-reference by anchor yields in accurate position

From: Juri Linkov <[email-masked]>
Date: Sun, 04 Apr 2010 01:04:45 +0300

>> IOW, using an after-string would probably be an OK compromise for 23.2
>> (better than dropping breadcrumbs altogether).
>
> I'll try to implement an after-string for 23.2.

To be able to click on links that are not part of the Info file
and don't have the "*Note" format, this patch adds two new commands
`Info-mouse-follow-link' and `Info-follow-link' plus a new keymap
`Info-link-keymap' (it's like `Info-up-link-keymap' and friends).

`Info-insert-breadcrumbs' is renamed to `Info-breadcrumbs'
that returns a string with links.

There are still a problem.  I can't find a way to move the cursor
inside the overlay's after-string and click links inside it.
Any suggestions?

=== modified file 'lisp/info.el'
--- lisp/info.el	2010-03-03 19:23:20 +0000
+++ lisp/info.el	2010-04-03 22:03:23 +0000
@@ -1053,8 +1053,6 @@ (defun Info-find-node-2 (filename nodena
 	    (Info-select-node)
 	    (goto-char (point-min))
 	    (forward-line 1)		       ; skip header line
-	    (when (> Info-breadcrumbs-depth 0) ; skip breadcrumbs line
-	      (forward-line 1))
 
 	    (cond (anchorpos
                    (let ((new-history (list Info-current-file
@@ -3551,6 +3549,20 @@ (defun Info-try-follow-nearest-node (&op
      ((setq node (Info-get-token (point) "Prev: " "Prev: \\([^,\n\t]*\\)"))
       (Info-goto-node node fork)))
     node))
+
+(defun Info-mouse-follow-link (click)
+  "Follow a link under point."
+  (interactive "e")
+  (mouse-set-point click)
+  (Info-follow-link))
+
+(defun Info-follow-link ()
+  "Follow a link under point."
+  (interactive)
+  (let ((link-args (get-text-property (point) 'link-args)))
+    (when link-args
+      (Info-goto-node link-args))))
+
 
 (defvar Info-mode-map
   (let ((map (make-keymap)))
@@ -4141,11 +4153,23 @@ (defvar Info-up-link-keymap
     keymap)
   "Keymap to put on the Up link in the text or the header line.")
 
-(defun Info-insert-breadcrumbs ()
+(defvar Info-link-keymap
+  (let ((keymap (make-sparse-keymap)))
+    (define-key keymap [header-line mouse-1] 'Info-mouse-follow-link)
+    (define-key keymap [header-line mouse-2] 'Info-mouse-follow-link)
+    (define-key keymap [header-line down-mouse-1] 'ignore)
+    (define-key keymap [mouse-2] 'Info-mouse-follow-link)
+    (define-key keymap [follow-link] 'mouse-face)
+    (define-key keymap "\r" 'Info-follow-link)
+    keymap)
+  "Keymap to put on the link in the text or the header line.")
+
+(defun Info-breadcrumbs ()
   (let ((nodes (Info-toc-nodes Info-current-file))
 	(node Info-current-node)
         (crumbs ())
-        (depth Info-breadcrumbs-depth))
+        (depth Info-breadcrumbs-depth)
+	line)
 
     ;; Get ancestors from the cached parent-children node info
     (while (and (not (equal "Top" node)) (> depth 0))
@@ -4172,15 +4196,24 @@ (defun Info-insert-breadcrumbs ()
 			     (file-name-nondirectory Info-current-file)
 			   ;; Some legacy code can still use a symbol.
 			   Info-current-file)))))
-	  (insert (if (bolp) "" " > ")
-		  (cond
-		   ((null node) "...")
-		   ((equal node Info-current-node)
-		    ;; No point linking to ourselves.
-		    (propertize text 'font-lock-face 'info-header-node))
-		   (t
-		    (concat "*Note " text "::"))))))
-      (insert "\n"))))
+	  (setq line (concat
+		      line
+		      (if (null line) "" " > ")
+		      (cond
+		       ((null node) "...")
+		       ((equal node Info-current-node)
+			;; No point linking to ourselves.
+			(propertize text 'font-lock-face 'info-header-node))
+		       (t
+			(propertize text
+				    'mouse-face 'highlight
+				    'font-lock-face 'info-header-xref
+				    'help-echo "mouse-2: Go to node"
+				    'keymap Info-link-keymap
+				    'link-args text)
+			))))))
+      (setq line (concat line "\n")))
+    line))
 
 (defun Info-fontify-node ()
   "Fontify the node."
@@ -4227,8 +4260,8 @@ (defun Info-fontify-node ()
 		((string-equal (downcase tag) "next") Info-next-link-keymap)
 		((string-equal (downcase tag) "up"  ) Info-up-link-keymap))))))
 
-        (when (> Info-breadcrumbs-depth 0)
-          (Info-insert-breadcrumbs))
+        ;; (when (> Info-breadcrumbs-depth 0)
+        ;;   (insert (Info-breadcrumbs)))
 
         ;; Treat header line.
         (when Info-use-header-line
@@ -4260,7 +4293,10 @@ (defun Info-fontify-node ()
             ;; that is in the header, if it is just part.
             (cond
              ((> Info-breadcrumbs-depth 0)
-              (put-text-property (point-min) (1+ header-end) 'invisible t))
+              (put-text-property (point-min) (1+ header-end) 'invisible t)
+	      (overlay-put
+	       (make-overlay header-end (1+ header-end))
+	       'after-string (propertize (Info-breadcrumbs) 'cursor t)))
              ((not (bobp))
               ;; Hide the punctuation at the end, too.
               (skip-chars-backward " \t,")

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