unofficial mirror of bug-gnu-emacs@gnu.org 
 help / color / mirror / code / Atom feed
* bug#60587: 30.0.50; Info pages are lacking links from symbol names to the symbol's help documentation
@ 2023-01-05 23:47 H. Dieter Wilhelm
  2023-01-06 19:03 ` bug#60587: Patch for adding links to symbols' " H. Dieter Wilhelm
  0 siblings, 1 reply; 58+ messages in thread
From: H. Dieter Wilhelm @ 2023-01-05 23:47 UTC (permalink / raw)
  To: 60587; +Cc: Ihor Radchenko, Eli Zaretskii, Stefan Monnier

Hello 

Here's the bug-report which was proposed in the thread

"Re: [ELPA] New package: inform"

on the mailing list emacs-devel.

When I tried to attach a patch to illustrate the point of this
bug-report I've got an error message that it is not possible to send bug
reports with an attachment!?  I'll attach the patch when I've received
the acknowledgement.

     Dieter
-- 
Best wishes
H. Dieter Wilhelm
Zwingenberg, Germany





^ permalink raw reply	[flat|nested] 58+ messages in thread

* bug#60587: Patch for adding links to symbols' help documentation
  2023-01-05 23:47 bug#60587: 30.0.50; Info pages are lacking links from symbol names to the symbol's help documentation H. Dieter Wilhelm
@ 2023-01-06 19:03 ` H. Dieter Wilhelm
  2023-01-07  7:38   ` Eli Zaretskii
  0 siblings, 1 reply; 58+ messages in thread
From: H. Dieter Wilhelm @ 2023-01-06 19:03 UTC (permalink / raw)
  To: 60587

[-- Attachment #1: Type: text/plain, Size: 244 bytes --]

Hello Emacs,

I attached a patch for the current master branch build from git
format-patch.  And spliced the code to implement the linking of symbols
in info manuals to the help documentation into lisp/info-xref.el.

Thank you for your review


[-- Attachment #2: 0001-Provide-in-Info-manuals-links-of-symbols-to-their-he.patch --]
[-- Type: text/x-diff, Size: 24299 bytes --]

From a7a90284bbe5a55dd0a4cdd0759698787db0a4be Mon Sep 17 00:00:00 2001
From: Dieter Wilhelm <dieter@duenenhof-wilhelm.de>
Date: Wed, 4 Jan 2023 20:50:15 +0100
Subject: [PATCH] Provide in Info manuals links of symbols to their help
 documentation

* lisp/info-xref.el contains all the necessary code.  It is separated
from the original code - for the moment - with lines of semi-colons.
---
 lisp/info-xref.el | 494 ++++++++++++++++++++++++++++++++++++++++++----
 1 file changed, 451 insertions(+), 43 deletions(-)

diff --git a/lisp/info-xref.el b/lisp/info-xref.el
index a910f38af84..6677ade1328 100644
--- a/lisp/info-xref.el
+++ b/lisp/info-xref.el
@@ -1,4 +1,4 @@
-;;; info-xref.el --- check external references in an Info document -*- lexical-binding: t -*-
+;;; info-xref.el --- Cross references in an Info document -*- lexical-binding:  t -*-
 
 ;; Copyright (C) 2003-2023 Free Software Foundation, Inc.
 
@@ -38,6 +38,119 @@
 ;; `M-x info-xref-docstrings' checks docstring "Info node ..." hyperlinks in
 ;; source files (and other files).
 
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+;; This library provides links of symbols (functions, variables,
+;; faces) within Emacs' Info viewer to their builtin help
+;; documentation.  This linking is done, when the symbol names in
+;; texinfo documentations (like the Emacs- and Elisp manual) are
+
+;; 1. Quoted symbol names like `quoted-symbol' or:
+
+;; 2. Function names are prefixed by M-x, for example M-x
+;; function-name or are quoted and prefixed like `M-x function-name'.
+
+;; 3. Function names appearing behind the following forms, which
+;; occur, for example, in the Elisp manual:
+
+;;   -- Special Form: function-name
+;;   -- Command:
+;;   -- Function:
+;;   -- Macro:
+
+;; 4. And variables names behind the following text:
+
+;;   -- User Option: variable-name
+;;   -- Variable:
+
+;; In any case all symbol names must be known to Emacs, i.e. their
+;; names are found in the variable `obarray'.
+
+;; You can follow the additional links with the usual Info
+;; keybindings.  The customisation variable
+;; `mouse-1-click-follows-link' is influencing the clicking behavior
+;; (and the tooltips) of the links, the variable's default is 450
+;; (milli seconds) setting it to nil means only clicking with mouse-2
+;; is following the link (hint: Drew Adams).
+
+;; The link color of symbols - referencing their builtin documentation
+;; - is distinct from links which are referencing further Info
+;; documentation.
+
+;; Inform is checking if the Info documents are relevant Elisp and
+;; Emacs related files to avoid false positives.  Please see the
+;; customization variable `inform-none-emacs-or-elisp-documents'.
+
+;; The code uses mostly mechanisms from Emacs' lisp/help-mode.el file.
+
+;;; Change Log:
+
+;; 1.3:
+
+;; Inform is checking if the Info documents are relevant Elisp and
+;; Emacs related files to avoid false positives.
+
+;; 1.2:
+
+;; Link Elisp descriptions of symbols to their help documentation,
+;; like the following function example: -- Function: eval form
+
+;; Distinguish color of texinfo links (`link' type) and Help links
+;; (`font-lock-function-name-face')
+
+;;; TODO:
+
+;; Currently inconsistent link colors to help buffers: In *info*
+;; different as in *Help* buffers!
+
+;; Check the application `inform-xref-symbol-regexp' for additional
+;; symbol prefixes without quoting of symbol-names
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; Does the following belong to customize.el?
+
+;; Generalise linking to "customization buffers" for the "easy
+;; customization" info documentation see also the customization
+;; section in the elisp manual
+
+;; - distinguish the Customization-links from Help- and Info-links
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+;;; Ideas:
+
+;; Link the help buffers back to higher level info manual subjects,
+;; similar to help-fns+.el from Drew Adams.
+
+;; Twice clicking or RETurning removes *Help* buffer (idea: Drew
+;; Adams)
+
+;; Different colors for different symbol types (idea: Drew Adams) see
+;; package helpful and info+ / info-colors on Melpa and see
+;; font-lock.el for common faces.
+
+;; - Do we need to indicate an already visited Help link with a
+;;   different color?
+
+;; - Would it be be good to overtake all colors of package
+;;   "info-colors"?
+
+;; - Do we need to distinguish the link FONTS? No, difficult to read!
+
+;; Back / Forward button in help buffer - back to info buffer or
+;; remain in help mode?
+
+;; Linking of standard symbol properties?
+
+;; - (info "(elisp) Standard Properties")
+
+;;  Elisp manual examples:
+;;       (symbol-name 'car) ... ?
+
+;; Shortening the verbose texinfo URLs?  But how to handle the changed
+;; indentation?
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
 ;;; History:
 
 ;; Version 3 - new M-x info-xref-docstrings, use compilation-mode
@@ -297,16 +410,16 @@ info-xref-check
   (interactive
    (list
     (let* ((default-filename
-             (cond ((eq major-mode 'Info-mode)
-                    Info-current-file)
-                   ((eq major-mode 'texinfo-mode)
-                    ;; look for @setfilename like makeinfo.el does
-                    (save-excursion
-                      (goto-char (point-min))
-                      (if (re-search-forward
-                           "^@setfilename[ \t]+\\([^ \t\n]+\\)[ \t]*"
-                           (line-beginning-position 100) t)
-                          (expand-file-name (match-string 1)))))))
+            (cond ((eq major-mode 'Info-mode)
+                   Info-current-file)
+                  ((eq major-mode 'texinfo-mode)
+                   ;; look for @setfilename like makeinfo.el does
+                   (save-excursion
+                     (goto-char (point-min))
+                     (if (re-search-forward
+                          "^@setfilename[ \t]+\\([^ \t\n]+\\)[ \t]*"
+                          (line-beginning-position 100) t)
+                         (expand-file-name (match-string 1)))))))
            (prompt (if default-filename
                        (format "Info file (%s): " default-filename)
                      "Info file: ")))
@@ -367,24 +480,24 @@ info-xref-all-info-files
 (defun info-xref-check-list (filename-list)
   "Check external references in info documents in FILENAME-LIST."
   (info-xref-with-output
-    (dolist (info-xref-filename filename-list)
-      (setq info-xref-xfile-alist nil)
-      (let ((info-xref-output-heading
-             (format "Info file %s\n" info-xref-filename)))
-        (with-temp-message (format "Looking at %s" info-xref-filename)
-          (with-temp-buffer
-            (info-insert-file-contents info-xref-filename)
-            (goto-char (point-min))
-            (if (search-forward "\^_\nIndirect:\n" nil t)
-                (let ((dir (file-name-directory info-xref-filename)))
-                  (while (looking-at "\\(.*\\): [0-9]+\n")
-                    (let ((info-xref-filename
-                           (expand-file-name (match-string 1) dir)))
-                      (with-temp-buffer
-                        (info-insert-file-contents info-xref-filename)
-                        (info-xref-check-buffer)))
-                    (forward-line)))
-              (info-xref-check-buffer))))))))
+   (dolist (info-xref-filename filename-list)
+     (setq info-xref-xfile-alist nil)
+     (let ((info-xref-output-heading
+            (format "Info file %s\n" info-xref-filename)))
+       (with-temp-message (format "Looking at %s" info-xref-filename)
+         (with-temp-buffer
+           (info-insert-file-contents info-xref-filename)
+           (goto-char (point-min))
+           (if (search-forward "\^_\nIndirect:\n" nil t)
+               (let ((dir (file-name-directory info-xref-filename)))
+                 (while (looking-at "\\(.*\\): [0-9]+\n")
+                   (let ((info-xref-filename
+                          (expand-file-name (match-string 1) dir)))
+                     (with-temp-buffer
+                       (info-insert-file-contents info-xref-filename)
+                       (info-xref-check-buffer)))
+                   (forward-line)))
+             (info-xref-check-buffer))))))))
 
 (defconst info-xref-node-re "\\(?1:\\(([^)]*)\\)[^.,]+\\)"
   "Regexp with subexp 1 matching (manual)node.")
@@ -513,7 +626,7 @@ info-xref-docstrings
 the sources handy."
   (interactive
    (let* ((default (and buffer-file-name
-                              (file-relative-name buffer-file-name)))
+                        (file-relative-name buffer-file-name)))
           (prompt (if default
                       (format "Filename with wildcards (%s): "
                               default)
@@ -539,23 +652,318 @@ info-xref-docstrings
      (setq info-xref-xfile-alist nil)  ;; "not found"s once per file
 
      (info-xref-with-file info-xref-filename
-       (goto-char (point-min))
-       (while (re-search-forward help-xref-info-regexp nil t)
-         (let ((node (match-string 2)))
-           (save-excursion
-             (goto-char (match-beginning 2)) ;; start of node as error position
+                          (goto-char (point-min))
+                          (while (re-search-forward help-xref-info-regexp nil t)
+                            (let ((node (match-string 2)))
+                              (save-excursion
+                                (goto-char (match-beginning 2)) ;; start of node as error position
+
+                                ;; skip nodes with "%" as probably `format' strings such as in
+                                ;; info-look.el
+                                (unless (string-search "%" node)
+
+                                  ;; "(emacs)" is the default manual for docstring hyperlinks,
+                                  ;; per `help-make-xrefs'
+                                  (unless (string-match "\\`(" node)
+                                    (setq node (concat "(emacs)" node)))
+
+                                  (info-xref-check-node node)))))))))
 
-             ;; skip nodes with "%" as probably `format' strings such as in
-             ;; info-look.el
-             (unless (string-search "%" node)
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
-               ;; "(emacs)" is the default manual for docstring hyperlinks,
-               ;; per `help-make-xrefs'
-               (unless (string-match "\\`(" node)
-                 (setq node (concat "(emacs)" node)))
+(require 'button)
+(require 'cl-lib)
+(require 'help-mode)                   ;redundant?
 
-               (info-xref-check-node node)))))))))
+;; activate inform without manually loading it. Is there a better way?
+;; ;;;###autoload (require 'info-xref)
 
+;; this is spawning lisp/info-xref.el's definition to 'info! This
+;; group is sorted now in 'docs and 'info! -FIXME-
+(defgroup info-xref nil
+  "Customisation 'info-xref' subgroup of info.
+Check external cross-references in Info documents and provide
+hyperlinks from symbols to their help documentation."
+  :group 'info)
+
+;;;###autoload
+(defcustom info-xref-make-xref-flag t
+  "Non-nil means create symbol links in info buffers."
+  :type '(choice (const :tag "Create links" t)
+                 (const :tag "Do not link" nil))
+  :group 'info-xref)
+
+(require 'cl-seq)
+;; Info-director-list must be initialised
+(info-initialize)
+(defvar Info-xref-emacs-info-dir-content
+  (mapcar 'file-name-nondirectory ;'file-name-sans-extension
+          (directory-files
+           (car
+            ;; search for the main Emacs' info/ directory
+            (cl-member "[^.]emacs" Info-directory-list :test 'string-match-p))
+           ;; don't list "." and ".."
+           t  "[^.]$"))
+  "List of file names in Emacs' own info/ directory.")
+
+;; Turn into regexp list necessary? Stefan
+;; Switch to alist with explanation of file name?
+(defcustom info-xref-none-emacs-or-elisp-documents
+  '("aarm2012" ; Stefan: Ada manual, Elpa archive
+    "arm2012"  ; Stefan: Ada manual
+    "sicp"   ; T.V: Structure and Interpretation of Computer Programs,
+                                        ; Melpa archive
+    )
+  "List of all none GNU-Emacs or Elisp documentation.
+Or other documents not to be checked for linking to their help
+documentation.  The list must contains only the base name of the
+files (without their file name extension \".info\")."
+  :type '(repeat string)
+  :group 'info-xref)
+
+(defun Info-xref-check-docu-p ()
+  "Check if the current info file is relevant to Emacs.
+That means `Info-current-file' is either found in Emacs' info/
+directory or in `package-user-dir' and is not included in the
+`info-xref-none-emacs-or-elisp-documents' list."
+  (let* ((ifile Info-current-file)
+         (ifi (when ifile
+                (file-name-sans-extension
+                 (file-name-nondirectory ifile))))
+         (pdir (when (boundp 'package-user-dir)
+                 (expand-file-name
+                  package-user-dir)))
+         (ifiles Info-xref-emacs-info-dir-content)
+         (ndocu info-xref-none-emacs-or-elisp-documents))
+    (and ifile
+         (or (assoc-string (concat ifi ".info") ifiles)
+             ;; info files might be archived!
+             (assoc-string (concat ifi ".info.gz") ifiles)
+             (when pdir (string-match pdir ifile)))
+         (not (assoc-string ifi ndocu)))))
+
+(defvar describe-symbol-backends)      ;from help-mode.el
+(defvar help-xref-following)           ;dito
+
+;; this toggles the complete linking process
+;;;###autoload
+(when info-xref-make-xref-flag
+  (add-hook 'Info-selection-hook 'Info-xref-make-xrefs))
+
+(defface Info-xref-color
+  '((t (:inherit font-lock-doc-face
+                 ;; font-lock-preprocessor-face ; similar to link face (default)
+                 ;; font-lock-builtin-face ; similar (default Emacs)
+                 ;; font-lock-function-name-face ; similar (default)
+                 ;; Info-xref-face
+                 )))
+  "Face for the `symbol' reference items in `info' nodes."
+  :group 'info-colors)
+
+;; Button types
+
+(define-button-type 'Info-xref
+  'link t                         ;for Info-next-reference-or-link
+  'follow-link t
+  'face 'Info-xref-color
+  'action #'Info-xref-button-action)
+
+(define-button-type 'Info-xref-function
+  :supertype 'Info-xref
+  'Info-xref-function 'describe-function
+  'Info-xref-echo (purecopy "mouse-2, RET: describe this function"))
+
+(define-button-type 'Info-xref-variable
+  :supertype 'Info-xref
+  'Info-xref-function 'describe-variable
+  'Info-xref-echo (purecopy "mouse-2, RET: describe this variable"))
+
+(define-button-type 'Info-xref-face
+  :supertype 'Info-xref
+  'Info-xref-function 'describe-face
+  'Info-xref-echo (purecopy "mouse-2, RET: describe this face"))
+
+(define-button-type 'Info-xref-symbol
+  :supertype 'Info-xref
+  'Info-xref-function #'describe-symbol
+  'Info-xref-echo (purecopy "mouse-2, RET: describe this symbol"))
+
+(define-button-type 'Info-xref-function-def
+  :supertype 'Info-xref
+  'Info-xref-function (lambda (fun &optional file type)
+                        (or file
+                            (setq file (find-lisp-object-file-name fun type)))
+                        (if (not file)
+                            (message "Unable to find defining file")
+                          (require 'find-func)
+                          (when (eq file 'C-source)
+                            (setq file
+                                  (help-C-file-name (indirect-function fun) 'fun)))
+                          ;; Don't use find-function-noselect because it follows
+                          ;; aliases (which fails for built-in functions).
+                          (let ((location
+                                 (find-function-search-for-symbol fun type file)))
+                            (pop-to-buffer (car location))
+                            (run-hooks 'find-function-after-hook)
+                            (if (cdr location)
+                                (goto-char (cdr location))
+                              (message "Unable to find location in file")))))
+  'Info-xref-echo (purecopy "mouse-2, RET: find function's definition"))
+
+;; Functions
+
+(defun Info-xref-button-action (button)
+  "Call BUTTON's help function."
+  (Info-xref-do-xref nil
+                     (button-get button 'Info-xref-function)
+                     (button-get button 'Info-xref-args)))
+
+(defun Info-xref-do-xref (_pos function args)
+  "Call the help cross-reference function FUNCTION with args ARGS.
+Things are set up properly so that the resulting `help-buffer' has
+a proper [back] button."
+  ;; There is a reference at point.  Follow it.
+  (let ((help-xref-following nil))
+    (apply
+     function (if (eq function 'info)
+                  (append args (list (generate-new-buffer-name "*info*")))args))))
+
+(defun Info-xref-button (match-number type &rest args)
+  "Make a hyperlink for cross-reference text previously matched.
+MATCH-NUMBER is the subexpression of interest in the last matched
+regexp.  TYPE is the type of button to use.  Any remaining arguments are
+passed to the button's Info-xref-function when it is invoked.
+See `Info-xref-make-xrefs' Don't forget ARGS." ; -TODO-
+  ;; Don't mung properties we've added specially in some instances.
+  (unless (button-at (match-beginning match-number))
+    ;; (message "Creating button: %s." args)
+    (make-text-button (match-beginning match-number)
+                      (match-end match-number)
+                      'type type 'Info-xref-args args)))
+
+(defconst Info-xref-symbol-regexp
+  (purecopy (concat "\\(\\<\\(\\(variable\\|option\\)\\|"  ; Link to var
+                    "\\(function\\|command\\|call\\)\\|"   ; Link to function
+                    "\\(face\\)\\|"                       ; Link to face
+                    "\\(symbol\\|program\\|property\\)\\|" ; Don't link
+                    "\\(source \\(?:code \\)?\\(?:of\\|for\\)\\)\\)"
+                    "[ \t\n]+\\)?"
+                    ;; Note starting with word-syntax character:
+                    "['`‘]\\(\\sw\\(\\sw\\|\\s_\\)+\\|`\\)['’]"))
+  "Regexp matching doc string references to symbols.
+
+The words preceding the quoted symbol can be used in doc strings to
+distinguish references to variables, functions and symbols.")
+
+;;;###autoload
+(defun Info-xref-make-xrefs (&optional buffer)
+  "Parse and hyperlink documentation cross-references in the given BUFFER.
+
+Find cross-reference information in a buffer and activate such cross
+references for selection with `help-follow'.  Cross-references have
+the canonical form `...'  and the type of reference may be
+disambiguated by the preceding word(s) used in
+`Info-xref-symbol-regexp'.
+
+Function names are also prefixed by \"M-x\", for example \"M-x
+function-name\" or are quoted and prefixed like `M-x
+function-name'.
+
+Also Function names appearing behind the following forms, which
+occur, for example, in the Elisp manual:
+
+ -- Special Form: function-name
+ -- Command:
+ -- Function:
+ -- Macro:
+
+And variables names behind the following text:
+
+ -- User Option: variable-name
+ -- Variable:
+
+Faces only get cross-referenced if preceded or followed by the
+word `face'.  Variables without variable documentation do not get
+cross-referenced, unless preceded by the word `variable' or
+`option'."
+  (interactive "b")
+  (when (Info-xref-check-docu-p)
+    (with-current-buffer (or buffer (current-buffer))
+      (save-excursion
+        (goto-char (point-min))
+        ;; Skip the header-type info, though it might be useful to parse
+        ;; it at some stage (e.g. "function in `library'").
+        ;;      (forward-paragraph)
+        (with-silent-modifications      ;from Stefan
+          (let (;(stab (syntax-table))
+                (case-fold-search t)
+                (inhibit-read-only t))
+            (with-syntax-table emacs-lisp-mode-syntax-table
+              ;; Quoted symbols
+              (save-excursion
+                (while (re-search-forward Info-xref-symbol-regexp nil t)
+                  (let* ((data (match-string 8))
+                         (sym (intern-soft data)))
+                    (if sym
+                        (cond
+                         ((match-string 3) ; `variable' &c
+                          (and (or (boundp sym) ; `variable' doesn't ensure
+                                        ; it's actually bound
+                                   (get sym 'variable-documentation))
+                               (Info-xref-button 8 'Info-xref-variable sym)))
+                         ((match-string 4) ; `function' &c
+                          (and (fboundp sym) ; similarly
+                               (Info-xref-button 8 'Info-xref-function sym)))
+                         ((match-string 5) ; `face'
+                          (and (facep sym)
+                               (Info-xref-button 8 'Info-xref-face sym)))
+                         ((match-string 6)) ; nothing for `symbol'
+                         ((match-string 7)
+                          (Info-xref-button 8 'Info-xref-function-def sym))
+                         ((cl-some (lambda (x) (funcall (nth 1 x) sym))
+                                   describe-symbol-backends)
+                          (Info-xref-button 8 'Info-xref-symbol sym)))))))
+
+              ;; (info "(elisp) Eval")
+              ;; Elisp manual      -- Special Form:
+              ;;                   -- Command:
+              ;;                   -- Function: function-name function
+              ;;                   -- Macro:
+              (save-excursion
+                (while (re-search-forward
+                        "-- \\(Special Form:\\|Command:\\|Function:\\|Macro:\\) "
+                        nil t)
+                  (looking-at "\\(\\sw\\|\\s_\\)+")
+                  (let ((sym (intern-soft (match-string 0))))
+                    (if (fboundp sym)
+                        (Info-xref-button 0 'Info-xref-function sym)))))
+
+              ;;              -- User Option:
+              ;;              -- Variable: variable-name
+              (save-excursion
+                (while (re-search-forward
+                        "-- \\(User Option:\\|Variable:\\) "
+                        nil t)
+                  (looking-at "\\(\\sw\\|\\s_\\)+")
+                  (let ((sym (intern-soft (match-string 0))))
+                    (if (boundp sym)
+                        (Info-xref-button 0 'Info-xref-variable sym)))))
+
+              ;; M-x prefixed functions
+              (save-excursion
+                (while (re-search-forward
+                        ;; Assume command name is only word and symbol
+                        ;; characters to get things like `use M-x foo->bar'.
+                        ;; Command required to end with word constituent
+                        ;; to avoid `.' at end of a sentence.
+                        ;; "\\<M-x\\s-+\\(\\sw\\(\\sw\\|\\s_\\)*\\sw\\)" nil t)
+                        ;; include M-x and quotes
+                        "['`‘]?M-x\\s-*\n?\\(\\sw\\(\\sw\\|\\s_\\)*\\sw\\)['’]?" nil t)
+                  (let ((sym (intern-soft (match-string 1))))
+                    ;; (message "found %s" sym)
+                    (if (fboundp sym)
+                        (Info-xref-button 1 'Info-xref-function sym))))))))))))
+;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
 (provide 'info-xref)
 
-- 
2.34.1


[-- Attachment #3: Type: text/plain, Size: 56 bytes --]


-- 
Best wishes
H. Dieter Wilhelm
Zwingenberg, Germany

^ permalink raw reply related	[flat|nested] 58+ messages in thread

* bug#60587: Patch for adding links to symbols' help documentation
  2023-01-06 19:03 ` bug#60587: Patch for adding links to symbols' " H. Dieter Wilhelm
@ 2023-01-07  7:38   ` Eli Zaretskii
  2023-01-08 20:06     ` H. Dieter Wilhelm
                       ` (2 more replies)
  0 siblings, 3 replies; 58+ messages in thread
From: Eli Zaretskii @ 2023-01-07  7:38 UTC (permalink / raw)
  To: H. Dieter Wilhelm, Stefan Monnier; +Cc: 60587

> From: "H. Dieter Wilhelm" <dieter@duenenhof-wilhelm.de>
> Date: Fri, 06 Jan 2023 20:03:23 +0100
> 
> I attached a patch for the current master branch build from git
> format-patch.  And spliced the code to implement the linking of symbols
> in info manuals to the help documentation into lisp/info-xref.el.

Thanks.

I think this should be in info.el, or maybe in a separate
info-SOMETHING.el file.  info-xref.el is for a certain job, of
interest primarily to Emacs maintainers, that is different from this
one, and I'm not sure conflating them is TRT.

More specific comments below.

> +;; This library provides links of symbols (functions, variables,

The "This library" part is a remnant of the previous life of this
code, and should be reworded to refer to specific command(s).

> +;; In any case all symbol names must be known to Emacs, i.e. their
> +;; names are found in the variable `obarray'.

I think a more useful way of saying this is

  In any case, the symbol must be known to Emacs, which means it is
  either a built-in, or its Lisp package is loaded in the current
  Emacs session, or the symbol is auto-loaded.

> +;; Inform is checking if the Info documents are relevant Elisp and
      ^^^^^^
This should be adapted to the "new life" of Inform as part of Emacs.

> +;; Emacs related files to avoid false positives.  Please see the
> +;; customization variable `inform-none-emacs-or-elisp-documents'.
                              ^^^^^^
And this.

> +;;; Change Log:
> +
> +;; 1.3:
> +
> +;; Inform is checking if the Info documents are relevant Elisp and
> +;; Emacs related files to avoid false positives.
> +
> +;; 1.2:
> +
> +;; Link Elisp descriptions of symbols to their help documentation,
> +;; like the following function example: -- Function: eval form
> +
> +;; Distinguish color of texinfo links (`link' type) and Help links
> +;; (`font-lock-function-name-face')

Not sure if it makes sense to keep this change log.

> +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
> +;; Does the following belong to customize.el?
> +
> +;; Generalise linking to "customization buffers" for the "easy
> +;; customization" info documentation see also the customization
> +;; section in the elisp manual
> +
> +;; - distinguish the Customization-links from Help- and Info-links
> +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
> +
> +;;; Ideas:
> +
> +;; Link the help buffers back to higher level info manual subjects,
> +;; similar to help-fns+.el from Drew Adams.
> +
> +;; Twice clicking or RETurning removes *Help* buffer (idea: Drew
> +;; Adams)
> +
> +;; Different colors for different symbol types (idea: Drew Adams) see
> +;; package helpful and info+ / info-colors on Melpa and see
> +;; font-lock.el for common faces.
> +
> +;; - Do we need to indicate an already visited Help link with a
> +;;   different color?
> +
> +;; - Would it be be good to overtake all colors of package
> +;;   "info-colors"?
> +
> +;; - Do we need to distinguish the link FONTS? No, difficult to read!
> +
> +;; Back / Forward button in help buffer - back to info buffer or
> +;; remain in help mode?
> +
> +;; Linking of standard symbol properties?
> +
> +;; - (info "(elisp) Standard Properties")
> +
> +;;  Elisp manual examples:
> +;;       (symbol-name 'car) ... ?
> +
> +;; Shortening the verbose texinfo URLs?  But how to handle the changed
> +;; indentation?
> +
> +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

Please review this part and decide which portions should be kept,
perhaps after a suitable rewording, and which should be removed.

> +(require 'button)
> +(require 'cl-lib)
> +(require 'help-mode)                   ;redundant?

If this is added to an existing file, there should be a ^L and some
heading-style command before it.

> +;; activate inform without manually loading it. Is there a better way?
> +;; ;;;###autoload (require 'info-xref)
>  
> +;; this is spawning lisp/info-xref.el's definition to 'info! This
> +;; group is sorted now in 'docs and 'info! -FIXME-

Comments should start with a capital letter.

> +;;;###autoload
> +(defcustom info-xref-make-xref-flag t
> +  "Non-nil means create symbol links in info buffers."
> +  :type '(choice (const :tag "Create links" t)
> +                 (const :tag "Do not link" nil))
> +  :group 'info-xref)

I think we frown on autoloading defcustoms.

Also, every new defcustom should have a :version tag.

> +;; Info-director-list must be initialised
           ^^^^^^^^  
Typo.  Also, comments should be complete sentences, and end with a
period (here and elsewhere in the patch).

> +(info-initialize)

Why do you need to call this? and why on top level?

> +;; Turn into regexp list necessary? Stefan
> +;; Switch to alist with explanation of file name?
> +(defcustom info-xref-none-emacs-or-elisp-documents
> +  '("aarm2012" ; Stefan: Ada manual, Elpa archive
> +    "arm2012"  ; Stefan: Ada manual
> +    "sicp"   ; T.V: Structure and Interpretation of Computer Programs,
> +                                        ; Melpa archive
> +    )
> +  "List of all none GNU-Emacs or Elisp documentation.
> +Or other documents not to be checked for linking to their help
> +documentation.  The list must contains only the base name of the
> +files (without their file name extension \".info\")."
> +  :type '(repeat string)
> +  :group 'info-xref)

Not sure what is this about, and what do the names above signify.
There are also typos: "none GNU-Emacs", "must contains".

> +(defun Info-xref-make-xrefs (&optional buffer)
> +  "Parse and hyperlink documentation cross-references in the given BUFFER.

The doc string should tell what happens if BUFFER is omitted or nil.

> +                (while (re-search-forward Info-xref-symbol-regexp nil t)
> +                  (let* ((data (match-string 8))
> +                         (sym (intern-soft data)))
> +                    (if sym
> +                        (cond
> +                         ((match-string 3) ; `variable' &c
> +                          (and (or (boundp sym) ; `variable' doesn't ensure
> +                                        ; it's actually bound
> +                                   (get sym 'variable-documentation))
> +                               (Info-xref-button 8 'Info-xref-variable sym)))
> +                         ((match-string 4) ; `function' &c
> +                          (and (fboundp sym) ; similarly
> +                               (Info-xref-button 8 'Info-xref-function sym)))
> +                         ((match-string 5) ; `face'
> +                          (and (facep sym)
> +                               (Info-xref-button 8 'Info-xref-face sym)))
> +                         ((match-string 6)) ; nothing for `symbol'
> +                         ((match-string 7)
> +                          (Info-xref-button 8 'Info-xref-function-def sym))
> +                         ((cl-some (lambda (x) (funcall (nth 1 x) sym))
> +                                   describe-symbol-backends)
> +                          (Info-xref-button 8 'Info-xref-symbol sym)))))))

Can this be rewritten so as to avoid the need for error-prone updates
of the sub-expression numbers every time Info-xref-symbol-regexp is
modified?

Finally, this needs additions to the user manual and NEWS.





^ permalink raw reply	[flat|nested] 58+ messages in thread

* bug#60587: Patch for adding links to symbols' help documentation
  2023-01-07  7:38   ` Eli Zaretskii
@ 2023-01-08 20:06     ` H. Dieter Wilhelm
  2023-01-09 12:46       ` Eli Zaretskii
  2023-01-13 23:33     ` H. Dieter Wilhelm
  2023-01-17 21:53     ` H. Dieter Wilhelm
  2 siblings, 1 reply; 58+ messages in thread
From: H. Dieter Wilhelm @ 2023-01-08 20:06 UTC (permalink / raw)
  To: Eli Zaretskii; +Cc: 60587, Stefan Monnier

[-- Attachment #1: Type: text/plain, Size: 7458 bytes --]

Eli Zaretskii <eliz@gnu.org> writes:

>> From: "H. Dieter Wilhelm" <dieter@duenenhof-wilhelm.de>
>> Date: Fri, 06 Jan 2023 20:03:23 +0100
>> 
>> I attached a patch for the current master branch build from git
>> format-patch.  And spliced the code to implement the linking of symbols
>> in info manuals to the help documentation into lisp/info-xref.el.
>
> Thanks.

No, thank you.  It's a pleasure to read your comments.

> I think this should be in info.el, or maybe in a separate
> info-SOMETHING.el file.  info-xref.el is for a certain job, of
> interest primarily to Emacs maintainers, that is different from this
> one, and I'm not sure conflating them is TRT.

Understood, it's now located in info.el.

>> +;; This library provides links of symbols (functions, variables,
>
> The "This library" part is a remnant of the previous life of this
> code, and should be reworded to refer to specific command(s).

Done.  (I'm sorry, I should have reviewed first this code from 2020.)

>> +;; In any case all symbol names must be known to Emacs, i.e. their
>> +;; names are found in the variable `obarray'.
>
> I think a more useful way of saying this is
>
>   In any case, the symbol must be known to Emacs, which means it is
>   either a built-in, or its Lisp package is loaded in the current
>   Emacs session, or the symbol is auto-loaded.

Absolutely, done

>> +;; Inform is checking if the Info documents are relevant Elisp and
>       ^^^^^^
> This should be adapted to the "new life" of Inform as part of Emacs.

Done

>> +;; Emacs related files to avoid false positives.  Please see the
>> +;; customization variable `inform-none-emacs-or-elisp-documents'.
>                               ^^^^^^
> And this.

Done

>> +;;; Change Log:
>> +
>> ...
>> +;; (`font-lock-function-name-face')
>
> Not sure if it makes sense to keep this change log.

Agreed and removed

>> +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
>> +;; Does the following belong to customize.el?
>> ....
>> +;;; Ideas:
>> +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
>
> Please review this part and decide which portions should be kept,
> perhaps after a suitable rewording, and which should be removed.

I removed above blather and kept it as private notes.

>> +(require 'button)
>> +(require 'cl-lib)
>> +(require 'help-mode)                   ;redundant?
>
> If this is added to an existing file, there should be a ^L and some
> heading-style command before it.

Sure, please let me learn about the application of "page markers" first.

>> +;; activate inform without manually loading it. Is there a better way?
>> +;; ;;;###autoload (require 'info-xref)
>>  
>> +;; this is spawning lisp/info-xref.el's definition to 'info! This
>> +;; group is sorted now in 'docs and 'info! -FIXME-
>
> Comments should start with a capital letter.

Done

>> +;;;###autoload
>> +(defcustom info-xref-make-xref-flag t
>> +  "Non-nil means create symbol links in info buffers."
>> +  :type '(choice (const :tag "Create links" t)
>> +                 (const :tag "Do not link" nil))
>> +  :group 'info-xref)
>
> I think we frown on autoloading defcustoms.

Removed it, I think above is redundant when the code resides in info.el,
anyway.

> Also, every new defcustom should have a :version tag.

Done

>> +;; Info-director-list must be initialised
>            ^^^^^^^^  
> Typo.  Also, comments should be complete sentences, and end with a
> period (here and elsewhere in the patch).

Done (I should have run checkdoc first, uuups there are lots of warnings
from the other code in info.el.)

>> +(info-initialize)
>
> Why do you need to call this? and why on top level?

Because I have no better idea to build info-emacs-info-dir-content
(maybe dynamically?).  With the code below I force the initialisation of
Info-directory-list. It is used for checking if the current info
document is relevant to Emacs.

;; We need to initalise Info-directory-list first.
(info-initialize)
;; Before declaring the following variable:
(defvar info-emacs-info-dir-content
  (mapcar 'file-name-nondirectory ;'file-name-sans-extension
          (directory-files
           (car
            ;; search for the main Emacs' info/ directory
            (cl-member "[^.]emacs" Info-directory-list :test 'string-match-p))
           ;; don't list "." and ".."
           t  "[^.]$"))
  "List of file names in Emacs' own info/ directory.")

>> +;; Turn into regexp list necessary? Stefan
>> +;; Switch to alist with explanation of file name?
>> +(defcustom info-xref-none-emacs-or-elisp-documents
>> +  '("aarm2012" ; Stefan: Ada manual, Elpa archive
>> +    "arm2012"  ; Stefan: Ada manual
>> +    "sicp"   ; T.V: Structure and Interpretation of Computer Programs,
>> +                                        ; Melpa archive
>> +    )
>> +  "List of all none GNU-Emacs or Elisp documentation.
>> +Or other documents not to be checked for linking to their help
>> +documentation.  The list must contains only the base name of the
>> +files (without their file name extension \".info\")."
>> +  :type '(repeat string)
>> +  :group 'info-xref)
>
> Not sure what is this about, and what do the names above signify.

This was a discussion on gmane.emacs.devel (please see
jwvtv0qv5av.fsf-monnier+emacs@gnu.org) on how to avoid trying to link
info documents which don't belong to Emacs. (Core-Utils, Ada
documentation from Melpa, etc.)

> There are also typos: "none GNU-Emacs", "must contains".

Done. 

>> +(defun Info-xref-make-xrefs (&optional buffer)
>> +  "Parse and hyperlink documentation cross-references in the given BUFFER.
>
> The doc string should tell what happens if BUFFER is omitted or nil.

Thank you, I'll take care about it.

>> +                (while (re-search-forward Info-xref-symbol-regexp nil t)
>> +                  (let* ((data (match-string 8))
>> +                         (sym (intern-soft data)))
>> +                    (if sym
>> +                        (cond
>> +                         ((match-string 3) ; `variable' &c
>> +                          (and (or (boundp sym) ; `variable' doesn't ensure
>> +                                        ; it's actually bound
>> +                                   (get sym 'variable-documentation))
>> +                               (Info-xref-button 8 'Info-xref-variable sym)))
>> +                         ((match-string 4) ; `function' &c
>> +                          (and (fboundp sym) ; similarly
>> +                               (Info-xref-button 8 'Info-xref-function sym)))
>> +                         ((match-string 5) ; `face'
>> +                          (and (facep sym)
>> +                               (Info-xref-button 8 'Info-xref-face sym)))
>> +                         ((match-string 6)) ; nothing for `symbol'
>> +                         ((match-string 7)
>> +                          (Info-xref-button 8 'Info-xref-function-def sym))
>> +                         ((cl-some (lambda (x) (funcall (nth 1 x) sym))
>> +                                   describe-symbol-backends)
>> +                          (Info-xref-button 8 'Info-xref-symbol sym)))))))
>
> Can this be rewritten so as to avoid the need for error-prone updates
> of the sub-expression numbers every time Info-xref-symbol-regexp is
> modified?

I'll try later, took note.

> Finally, this needs additions to the user manual and NEWS.

Alright, I took a note for working on this.

Thank you :-)


[-- Attachment #2: info.patch --]
[-- Type: text/x-diff, Size: 14949 bytes --]

diff --git a/lisp/info.el b/lisp/info.el
index 035dff66e75..f7153af5b26 100644
--- a/lisp/info.el
+++ b/lisp/info.el
@@ -5510,6 +5510,339 @@ info--manual-names
 					     Info-directory-list
 					     (mapcar #'car Info-suffix-list))))))))
 
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; This code below provides links of symbols (functions, variables,
+;; faces) within Emacs' Info viewer to their builtin help
+;; documentation.  This linking is done, when the symbol names in
+;; texinfo documentations (like the Emacs- and Elisp manual) are
+
+;; 1. Quoted symbol names like `quoted-symbol' or:
+
+;; 2. Function names are prefixed by M-x, for example M-x
+;; function-name or are quoted and prefixed like `M-x function-name'.
+
+;; 3. Function names appearing behind the following forms, which
+;; occur, for example, in the Elisp manual:
+
+;;   -- Special Form: function-name
+;;   -- Command: ...
+;;   -- Function: ...
+;;   -- Macro: ...
+
+;; 4. And variables names behind the following text:
+
+;;   -- User Option: variable-name
+;;   -- Variable: ...
+
+;; In any case all symbol names must be known to Emacs, which means it
+;; is either a built-in, or its Lisp package is loaded in the current
+;; Emacs session, or the symbol is auto-loaded.
+
+;; You can follow the additional links with the usual Info
+;; keybindings.  The customisation variable
+;; `mouse-1-click-follows-link' is influencing the clicking behavior
+;; (and the tooltips) of the links, the variable's default is 450
+;; (milli seconds) setting it to nil means only clicking with mouse-2
+;; is following the link (hint: Drew Adams).
+
+;; The link color of symbols - referencing their builtin documentation
+;; - is distinct from links which are referencing further Info
+;; documentation.
+
+;; Below code is checking if Info documents are relevant Elisp and
+;; Emacs related files to avoid false positives.  Please see the
+;; customization variable `info-none-emacs-or-elisp-documents'.
+
+;; The code uses mostly mechanisms from Emacs' lisp/help-mode.el file.
+
+
+
+(require 'button)
+(require 'cl-lib)
+(require 'help-mode)                   ;redundant?
+(require 'cl-seq)
+
+(defcustom info-make-xref-flag t
+  "Non-nil means create symbol links in info buffers.
+Please see the function `info-make-xrefs' for further
+information."
+  :type '(choice (const :tag "Create links" t)
+                 (const :tag "Do not link" nil))
+  :version "30.1"
+  :group 'info)
+
+;; We need to initalise Info-directory-list first.
+(info-initialize)
+;; Before declaring the following:
+(defvar info-emacs-info-dir-content
+  (mapcar 'file-name-nondirectory ;'file-name-sans-extension
+          (directory-files
+           (car
+            ;; search for the main Emacs' info/ directory
+            (cl-member "[^.]emacs" Info-directory-list :test 'string-match-p))
+           ;; don't list "." and ".."
+           t  "[^.]$"))
+  "List of file names in Emacs' own info/ directory.")
+
+;; FIXME: Turn into regexp list? Hint Stefan Monier or switch to alist
+;; with explanation of file name?
+(defcustom info-none-emacs-or-elisp-documents
+  '("aarm2012" ; Stefan: Ada manual, Elpa archive
+    "arm2012"  ; Stefan: Ada manual
+    "sicp"   ; T.V: Structure and Interpretation of Computer Programs,
+                                        ; Melpa archive
+    )
+  "List of all none GNU Emacs or Elisp documentation.
+Or other documents not to be checked for linking to their help
+documentation.  The list must contain only the base name of the
+files (without their file name extension \".info\")."
+  :type '(repeat string)
+  :version "30.1"
+  :group 'info)
+
+(defun info-check-docu-p ()
+  "Check if the current info file is relevant to Emacs.
+That means `Info-current-file' is either found in Emacs' info/
+directory or in `package-user-dir' and is not included in the
+`info-none-emacs-or-elisp-documents' list."
+  (let* ((ifile Info-current-file)
+         (ifi (when ifile
+                (file-name-sans-extension
+                 (file-name-nondirectory ifile))))
+         (pdir (when (boundp 'package-user-dir)
+                 (expand-file-name
+                  package-user-dir)))
+         (ifiles info-emacs-info-dir-content)
+         (ndocu info-none-emacs-or-elisp-documents))
+    (and ifile
+         (or (assoc-string (concat ifi ".info") ifiles)
+             ;; info files might be archived!
+             (assoc-string (concat ifi ".info.gz") ifiles)
+             (when pdir (string-match pdir ifile)))
+         (not (assoc-string ifi ndocu)))))
+
+;; FIXME: what are these variables for, suppress compiler warnings?
+(defvar describe-symbol-backends)      ;from help-mode.el
+(defvar help-xref-following)           ;dito
+
+;; This toggles the complete linking process
+(when info-make-xref-flag
+  (add-hook 'Info-selection-hook 'info-make-xrefs))
+
+(defface info-color
+  '((t (:inherit font-lock-doc-face
+                 ;; font-lock-preprocessor-face ; similar to link face (default)
+                 ;; font-lock-builtin-face ; similar (default Emacs)
+                 ;; font-lock-function-name-face ; similar (default)
+                 ;; info-face
+                 )))
+  "Face for the `symbol' reference items in `info' nodes."
+  :group 'info-colors)
+
+;; Button types
+
+(define-button-type 'info
+  'link t                         ;for Info-next-reference-or-link
+  'follow-link t
+  'face 'info-color
+  'action #'info-button-action)
+
+(define-button-type 'info-function
+  :supertype 'info
+  'info-function 'describe-function
+  'info-echo (purecopy "mouse-2, RET: describe this function"))
+
+(define-button-type 'info-variable
+  :supertype 'info
+  'info-function 'describe-variable
+  'info-echo (purecopy "mouse-2, RET: describe this variable"))
+
+(define-button-type 'info-face
+  :supertype 'info
+  'info-function 'describe-face
+  'info-echo (purecopy "mouse-2, RET: describe this face"))
+
+(define-button-type 'info-symbol
+  :supertype 'info
+  'info-function #'describe-symbol
+  'info-echo (purecopy "mouse-2, RET: describe this symbol"))
+
+(define-button-type 'info-function-def
+  :supertype 'info
+  'info-function (lambda (fun &optional file type)
+                        (or file
+                            (setq file (find-lisp-object-file-name fun type)))
+                        (if (not file)
+                            (message "Unable to find defining file")
+                          (require 'find-func)
+                          (when (eq file 'C-source)
+                            (setq file
+                                  (help-C-file-name (indirect-function fun) 'fun)))
+                          ;; Don't use find-function-noselect because it follows
+                          ;; aliases (which fails for built-in functions).
+                          (let ((location
+                                 (find-function-search-for-symbol fun type file)))
+                            (pop-to-buffer (car location))
+                            (run-hooks 'find-function-after-hook)
+                            (if (cdr location)
+                                (goto-char (cdr location))
+                              (message "Unable to find location in file")))))
+  'info-echo (purecopy "mouse-2, RET: find function's definition"))
+
+;; Functions
+
+(defun info-button-action (button)
+  "Call BUTTON's help function."
+  (info-do-xref nil
+                     (button-get button 'info-function)
+                     (button-get button 'info-args)))
+
+(defun info-do-xref (_pos function args)
+  "Call the help cross-reference function FUNCTION with args ARGS.
+Things are set up properly so that the resulting `help-buffer' has
+a proper [back] button."
+  ;; There is a reference at point.  Follow it.
+  (let ((help-xref-following nil))
+    (apply
+     function (if (eq function 'info)
+                  (append args (list (generate-new-buffer-name "*info*")))args))))
+
+(defun info-button (match-number type &rest args)
+  "Make a hyperlink for cross-reference text previously matched.
+MATCH-NUMBER is the subexpression of interest in the last matched
+regexp.  TYPE is the type of button to use.  Any remaining arguments are
+passed to the button's info-function when it is invoked.
+See `info-make-xrefs' Don't forget ARGS." ; -TODO-
+  ;; Don't mung properties we've added specially in some instances.
+  (unless (button-at (match-beginning match-number))
+    ;; (message "Creating button: %s." args)
+    (make-text-button (match-beginning match-number)
+                      (match-end match-number)
+                      'type type 'info-args args)))
+
+(defconst info-symbol-regexp
+  (purecopy (concat "\\(\\<\\(\\(variable\\|option\\)\\|"  ; Link to var
+                    "\\(function\\|command\\|call\\)\\|"   ; Link to function
+                    "\\(face\\)\\|"                       ; Link to face
+                    "\\(symbol\\|program\\|property\\)\\|" ; Don't link
+                    "\\(source \\(?:code \\)?\\(?:of\\|for\\)\\)\\)"
+                    "[ \t\n]+\\)?"
+                    ;; Note starting with word-syntax character:
+                    "['`‘]\\(\\sw\\(\\sw\\|\\s_\\)+\\|`\\)['’]"))
+  "Regexp matching info document references to their help references.
+The words preceding the quoted symbol can be used in doc strings to
+distinguish references to variables, functions and symbols.")
+
+;;;###autoload
+(defun info-make-xrefs (&optional buffer)
+  "Parse and hyperlink documentation cross-references in the given BUFFER.
+Find cross-reference information in a buffer and activate such cross
+references for selection with `help-follow'.  Cross-references have
+the canonical form `...'  and the type of reference may be
+disambiguated by the preceding word(s) used in
+`info-symbol-regexp'.
+
+Function names are also prefixed by \"M-x\", for example \"M-x
+function-name\" or are quoted and prefixed like `M-x
+function-name'.
+
+Also Function names appearing behind the following forms, which
+occur, for example, in the Elisp manual:
+
+ -- Special Form: function-name
+ -- Command: ...
+ -- Function: ...
+ -- Macro: ...
+
+And variables names behind the following text:
+
+ -- User Option: variable-name
+ -- Variable: ...
+
+Faces only get cross-referenced if preceded or followed by the
+word `face'.  Variables without variable documentation do not get
+cross-referenced, unless preceded by the word `variable' or
+`option'."
+  (interactive "b")
+  (when (info-check-docu-p)
+    (with-current-buffer (or buffer (current-buffer))
+      (save-excursion
+        (goto-char (point-min))
+        ;; Skip the header-type info, though it might be useful to parse
+        ;; it at some stage (e.g. "function in `library'").
+        ;;      (forward-paragraph)
+        (with-silent-modifications      ;from Stefan
+          (let (;(stab (syntax-table))
+                (case-fold-search t)
+                (inhibit-read-only t))
+            (with-syntax-table emacs-lisp-mode-syntax-table
+              ;; Quoted symbols
+              (save-excursion
+                (while (re-search-forward info-symbol-regexp nil t)
+                  (let* ((data (match-string 8))
+                         (sym (intern-soft data)))
+                    (if sym
+                        (cond
+                         ((match-string 3) ; `variable' &c
+                          (and (or (boundp sym) ; `variable' doesn't ensure
+                                        ; it's actually bound
+                                   (get sym 'variable-documentation))
+                               (info-button 8 'info-variable sym)))
+                         ((match-string 4) ; `function' &c
+                          (and (fboundp sym) ; similarly
+                               (info-button 8 'info-function sym)))
+                         ((match-string 5) ; `face'
+                          (and (facep sym)
+                               (info-button 8 'info-face sym)))
+                         ((match-string 6)) ; nothing for `symbol'
+                         ((match-string 7)
+                          (info-button 8 'info-function-def sym))
+                         ((cl-some (lambda (x) (funcall (nth 1 x) sym))
+                                   describe-symbol-backends)
+                          (info-button 8 'info-symbol sym)))))))
+
+              ;; (info "(elisp) Eval")
+              ;; Elisp manual      -- Special Form:
+              ;;                   -- Command:
+              ;;                   -- Function: function-name function
+              ;;                   -- Macro:
+              (save-excursion
+                (while (re-search-forward
+                        "-- \\(Special Form:\\|Command:\\|Function:\\|Macro:\\) "
+                        nil t)
+                  (looking-at "\\(\\sw\\|\\s_\\)+")
+                  (let ((sym (intern-soft (match-string 0))))
+                    (if (fboundp sym)
+                        (info-button 0 'info-function sym)))))
+
+              ;;              -- User Option:
+              ;;              -- Variable: variable-name
+              (save-excursion
+                (while (re-search-forward
+                        "-- \\(User Option:\\|Variable:\\) "
+                        nil t)
+                  (looking-at "\\(\\sw\\|\\s_\\)+")
+                  (let ((sym (intern-soft (match-string 0))))
+                    (if (boundp sym)
+                        (info-button 0 'info-variable sym)))))
+
+              ;; M-x prefixed functions
+              (save-excursion
+                (while (re-search-forward
+                        ;; Assume command name is only word and symbol
+                        ;; characters to get things like `use M-x foo->bar'.
+                        ;; Command required to end with word constituent
+                        ;; to avoid `.' at end of a sentence.
+                        ;; "\\<M-x\\s-+\\(\\sw\\(\\sw\\|\\s_\\)*\\sw\\)" nil t)
+                        ;; include M-x and quotes
+                        "['`‘]?M-x\\s-*\n?\\(\\sw\\(\\sw\\|\\s_\\)*\\sw\\)['’]?" nil t)
+                  (let ((sym (intern-soft (match-string 1))))
+                    ;; (message "found %s" sym)
+                    (if (fboundp sym)
+                        (info-button 1 'info-function sym))))))))))))
+;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+
 (provide 'info)
 
 ;;; info.el ends here

[-- Attachment #3: Type: text/plain, Size: 57 bytes --]



-- 
Best wishes
H. Dieter Wilhelm
Zwingenberg, Germany

^ permalink raw reply related	[flat|nested] 58+ messages in thread

* bug#60587: Patch for adding links to symbols' help documentation
  2023-01-08 20:06     ` H. Dieter Wilhelm
@ 2023-01-09 12:46       ` Eli Zaretskii
  2023-01-09 14:25         ` Stefan Monnier via Bug reports for GNU Emacs, the Swiss army knife of text editors
  2023-01-09 20:01         ` H. Dieter Wilhelm
  0 siblings, 2 replies; 58+ messages in thread
From: Eli Zaretskii @ 2023-01-09 12:46 UTC (permalink / raw)
  To: H. Dieter Wilhelm; +Cc: 60587, monnier

> From: "H. Dieter Wilhelm" <dieter@duenenhof-wilhelm.de>
> Cc: Stefan Monnier <monnier@iro.umontreal.ca>,  60587@debbugs.gnu.org
> Date: Sun, 08 Jan 2023 21:06:01 +0100
> 
> >> +(info-initialize)
> >
> > Why do you need to call this? and why on top level?
> 
> Because I have no better idea to build info-emacs-info-dir-content
> (maybe dynamically?).  With the code below I force the initialisation of
> Info-directory-list. It is used for checking if the current info
> document is relevant to Emacs.

Info-directory-list starts as nil, so you can test its value.

More generally, this feature displays links in an Info buffer, right?
If an Info buffer is displayed in Emacs, info-initialize was already
called, and you don't need to call it again.

> >> +;; Turn into regexp list necessary? Stefan
> >> +;; Switch to alist with explanation of file name?
> >> +(defcustom info-xref-none-emacs-or-elisp-documents
> >> +  '("aarm2012" ; Stefan: Ada manual, Elpa archive
> >> +    "arm2012"  ; Stefan: Ada manual
> >> +    "sicp"   ; T.V: Structure and Interpretation of Computer Programs,
> >> +                                        ; Melpa archive
> >> +    )
> >> +  "List of all none GNU-Emacs or Elisp documentation.
> >> +Or other documents not to be checked for linking to their help
> >> +documentation.  The list must contains only the base name of the
> >> +files (without their file name extension \".info\")."
> >> +  :type '(repeat string)
> >> +  :group 'info-xref)
> >
> > Not sure what is this about, and what do the names above signify.
> 
> This was a discussion on gmane.emacs.devel (please see
> jwvtv0qv5av.fsf-monnier+emacs@gnu.org) on how to avoid trying to link
> info documents which don't belong to Emacs. (Core-Utils, Ada
> documentation from Melpa, etc.)

I cannot access that discussion with this URL (can you tell on which
date that happened? then I will look in the emacs-devel list
archives), and I don't think I understand how such names will creep
into this feature.  Does the code somehow search every Info manual on
the system to do its job?





^ permalink raw reply	[flat|nested] 58+ messages in thread

* bug#60587: Patch for adding links to symbols' help documentation
  2023-01-09 12:46       ` Eli Zaretskii
@ 2023-01-09 14:25         ` Stefan Monnier via Bug reports for GNU Emacs, the Swiss army knife of text editors
  2023-01-09 20:01         ` H. Dieter Wilhelm
  1 sibling, 0 replies; 58+ messages in thread
From: Stefan Monnier via Bug reports for GNU Emacs, the Swiss army knife of text editors @ 2023-01-09 14:25 UTC (permalink / raw)
  To: Eli Zaretskii; +Cc: H. Dieter Wilhelm, 60587

> I cannot access that discussion with this URL (can you tell on which
> date that happened? then I will look in the emacs-devel list
> archives), and I don't think I understand how such names will creep
> into this feature.  Does the code somehow search every Info manual on
> the system to do its job?

More or less, yes.  IIRC it tries to limit itself to ELisp-related
manuals by avoiding all the manual except those that are in Emacs's own
`info` directory and those that are inside ELPA-installed packages.
Hence the list of exceptions being sicp and ada manuals since these can
be installed as ELPA packages.


        Stefan






^ permalink raw reply	[flat|nested] 58+ messages in thread

* bug#60587: Patch for adding links to symbols' help documentation
  2023-01-09 12:46       ` Eli Zaretskii
  2023-01-09 14:25         ` Stefan Monnier via Bug reports for GNU Emacs, the Swiss army knife of text editors
@ 2023-01-09 20:01         ` H. Dieter Wilhelm
  1 sibling, 0 replies; 58+ messages in thread
From: H. Dieter Wilhelm @ 2023-01-09 20:01 UTC (permalink / raw)
  To: Eli Zaretskii; +Cc: 60587, monnier

Eli Zaretskii <eliz@gnu.org> writes:
>> >> +(info-initialize)
>> >
>> > Why do you need to call this? and why on top level?
>> 
>> Because I have no better idea to build info-emacs-info-dir-content
>> (maybe dynamically?).  With the code below I force the initialisation of
>> Info-directory-list. It is used for checking if the current info
>> document is relevant to Emacs.
>
> Info-directory-list starts as nil, so you can test its value.
> More generally, this feature displays links in an Info buffer, right?
> If an Info buffer is displayed in Emacs, info-initialize was already
> called, and you don't need to call it again.

That is true. It was not much work to avoid it. :-)

>> >> +;; Turn into regexp list necessary? Stefan
>> >> +;; Switch to alist with explanation of file name?
>> >> +(defcustom info-xref-none-emacs-or-elisp-documents
>> >> +  '("aarm2012" ; Stefan: Ada manual, Elpa archive
>> >> +    "arm2012"  ; Stefan: Ada manual
>> >> +    "sicp"   ; T.V: Structure and Interpretation of Computer Programs,
>> >> +                                        ; Melpa archive
>> >> +    )
>> >> +  "List of all none GNU-Emacs or Elisp documentation.
>> >> +Or other documents not to be checked for linking to their help
>> >> +documentation.  The list must contains only the base name of the
>> >> +files (without their file name extension \".info\")."
>> >> +  :type '(repeat string)
>> >> +  :group 'info-xref)
>> >
>> > Not sure what is this about, and what do the names above signify.
>> 
>> This was a discussion on gmane.emacs.devel (please see
>> jwvtv0qv5av.fsf-monnier+emacs@gnu.org) on how to avoid trying to link
>> info documents which don't belong to Emacs. (Core-Utils, Ada
>> documentation from Melpa, etc.)
>
> I cannot access that discussion with this URL (can you tell on which
> date that happened? then I will look in the emacs-devel list
> archives)

Please have a look here:
https://lists.gnu.org/archive/html/emacs-devel/2020-05/msg00994.html
(Above is the message-id from 2020-05-08)

> , and I don't think I understand how such names will creep
> into this feature.  Does the code somehow search every Info manual on
> the system to do its job?

It's not searching, just checking whether Info-current-file has an
extension of .info(.gz) (this is redundant on my system but I forgot to
document in what circumstances this check might be necessary) and is
included in any of the Info-directory-list directories.

Since Info-directory-list may contain info files which are not related
to Emacs, it checks against the "blacklist"
info-none-emacs-or-elisp-documents.  E.g. from Elpa there are packages,
like sicp (Structure and Interpretation of Computer Programs) in info
format.

(defun info-check-docu-p ()
  "Check if the current info file is relevant to Emacs.
That means `Info-current-file' is either found in Emacs' info/
directory or in `package-user-dir' and is not included in the
`info-none-emacs-or-elisp-documents' list."
  (unless info-emacs-info-dir-content
    (info-compile-emacs-info-dir-content))
  (let* ((ifile Info-current-file)
         (ifi (when ifile
                (file-name-sans-extension
                 (file-name-nondirectory ifile))))
         (pdir (when (boundp 'package-user-dir)
                 (expand-file-name
                  package-user-dir)))
         ;; FIXME: Check if pdir is redundant because Package adds
         ;; info package folders to Info-directory-list anyway
         (ifiles info-emacs-info-dir-content)
         (ndocu info-none-emacs-or-elisp-documents))
    (and ifile
         (or (assoc-string (concat ifi ".info") ifiles)
             ;; info files might be archived!
             (assoc-string (concat ifi ".info.gz") ifiles)
             (when pdir (string-match pdir ifile)))
         (not (assoc-string ifi ndocu)))))


-- 
Best wishes)
H. Dieter Wilhelm
Zwingenberg, Germany





^ permalink raw reply	[flat|nested] 58+ messages in thread

* bug#60587: Patch for adding links to symbols' help documentation
  2023-01-07  7:38   ` Eli Zaretskii
  2023-01-08 20:06     ` H. Dieter Wilhelm
@ 2023-01-13 23:33     ` H. Dieter Wilhelm
  2023-01-14  7:12       ` Eli Zaretskii
  2023-01-17 21:53     ` H. Dieter Wilhelm
  2 siblings, 1 reply; 58+ messages in thread
From: H. Dieter Wilhelm @ 2023-01-13 23:33 UTC (permalink / raw)
  To: Eli Zaretskii; +Cc: 60587, Stefan Monnier

Eli Zaretskii <eliz@gnu.org> writes:

>> +(require 'button)
>> +(require 'cl-lib)
>> +(require 'help-mode)                   ;redundant?
>
> If this is added to an existing file, there should be a ^L and some
> heading-style command before it.

I had a look at the usage of ^L in info.el but I can't discern any rule
or consistency.  The number of lines between its page delimiters are
over 900 and below 20.  I assume you want me to use ^L to separate a
different topic within info.el?

>> +                (while (re-search-forward Info-xref-symbol-regexp nil t)
>> +                  (let* ((data (match-string 8))
>> +                         (sym (intern-soft data)))
>> +                    (if sym
>> +                        (cond
>> +                         ((match-string 3) ; `variable' &c
>> +                          (and (or (boundp sym) ; `variable' doesn't ensure
>> +                                        ; it's actually bound
>> +                                   (get sym 'variable-documentation))
>> +                               (Info-xref-button 8 'Info-xref-variable sym)))
>> +                         ((match-string 4) ; `function' &c
>> +                          (and (fboundp sym) ; similarly
>> +                               (Info-xref-button 8 'Info-xref-function sym)))
>> +                         ((match-string 5) ; `face'
>> +                          (and (facep sym)
>> +                               (Info-xref-button 8 'Info-xref-face sym)))
>> +                         ((match-string 6)) ; nothing for `symbol'
>> +                         ((match-string 7)
>> +                          (Info-xref-button 8 'Info-xref-function-def sym))
>> +                         ((cl-some (lambda (x) (funcall (nth 1 x) sym))
>> +                                   describe-symbol-backends)
>> +                          (Info-xref-button 8 'Info-xref-symbol sym)))))))
>
> Can this be rewritten so as to avoid the need for error-prone updates
> of the sub-expression numbers every time Info-xref-symbol-regexp is
> modified?

What do you think about the following approach?

(defcustom info-symbol-context
  '(( variable . "variable\\|option")
    ;; defining symbol as variable
    ( function . "function\\|command\\|call")
    ;; defining symbol as function
    ( face . "face")
    ;; defining symbol as face
    ( ignore . "symbol\\|program\\|property")
    ;; ignore symbols following this context type
    ( definition . "source \\(?:code \\)?\\(?:of\\|for\\)"))
    ;; function definitions in files
  "Help."
  :type 'list
  :version "30.1"
  :group 'info)


;; Assembling the complete regexp
(defvar info-symbol-regexp
  (concat
   ;; context
   "\\(" ; ---- context start
   "\\<\\(" ; contex definition
   (string-remove-suffix
    "\\|"
    (mapconcat
     (lambda (x) (concat "\\(" (cdr x) "\\)\\|"))
     info-symbol-context ""))
   "\\)"  ; --- definition end
   "[ \t\n]+" ; --- separators to quoted symbols
   "\\)?"  ;; ---- end of context
   ;; quoted symbol
   "['`‘]"	  ; start quotes
   ;; Note: symbol starting with word-syntax character:
   "\\(\\sw\\(\\sw\\|\\s_\\)+\\|`\\)" ; symbol
   "['’]"				  ; end quotes
   )
  "Help.")


;; helper function
(defun info-check-type( type)
  "Check if TYPE corresponds to the current search result.
`match-string'."
  (let ((ictr info-symbol-regexp)
	(n 3)                           ;embedded within 2 groups
	)
    (while (not (eq type (caar ictr)))
       (setq n (1+ n))
       (setq ictr (cdr ictr)))
    (match-string n)
    ))

;;Here comes the function creating links
;;....
                (while (re-search-forward info-symbol-regexp nil t)
                  (let* ((data (match-string 8))
                         (sym (intern-soft data)))
                    (if sym
                        (cond
                         ((info-check-type 'variable)
                          (and (or (boundp sym)
                                   (get sym 'variable-documentation))
                               (info-button 8 'info-variable sym)))
                         ((info-check-type 'function)
                          (and (fboundp sym)
                               (info-button 8 'info-function sym)))
                         ((info-check-type 'face)
                          (and (facep sym)
                               (info-button 8 'info-face sym)))
                         ((info-check-type 'ignore))
                         ((info-check-type 'definition)
                          (info-button 8 'info-function-def sym))
                         ;; 
                         ((cl-some (lambda (x) (funcall (nth 1 x) sym))
                                   describe-symbol-backends)
                          (info-button 8 'info-symbol sym)))))))




-- 
Best wishes
H. Dieter Wilhelm
Zwingenberg, Germany





^ permalink raw reply	[flat|nested] 58+ messages in thread

* bug#60587: Patch for adding links to symbols' help documentation
  2023-01-13 23:33     ` H. Dieter Wilhelm
@ 2023-01-14  7:12       ` Eli Zaretskii
  2023-01-15 12:48         ` H. Dieter Wilhelm
  0 siblings, 1 reply; 58+ messages in thread
From: Eli Zaretskii @ 2023-01-14  7:12 UTC (permalink / raw)
  To: H. Dieter Wilhelm; +Cc: 60587, monnier

> From: "H. Dieter Wilhelm" <dieter@duenenhof-wilhelm.de>
> Cc: Stefan Monnier <monnier@iro.umontreal.ca>,  60587@debbugs.gnu.org
> Date: Sat, 14 Jan 2023 00:33:19 +0100
> 
> Eli Zaretskii <eliz@gnu.org> writes:
> 
> >> +(require 'button)
> >> +(require 'cl-lib)
> >> +(require 'help-mode)                   ;redundant?
> >
> > If this is added to an existing file, there should be a ^L and some
> > heading-style command before it.
> 
> I had a look at the usage of ^L in info.el but I can't discern any rule
> or consistency.  The number of lines between its page delimiters are
> over 900 and below 20.  I assume you want me to use ^L to separate a
> different topic within info.el?

Yes.  This has nothing to do with the size of each topic's code.

> > Can this be rewritten so as to avoid the need for error-prone updates
> > of the sub-expression numbers every time Info-xref-symbol-regexp is
> > modified?
> 
> What do you think about the following approach?

Something like that, yes.  However, ...

> (defcustom info-symbol-context
>   '(( variable . "variable\\|option")
>     ;; defining symbol as variable
>     ( function . "function\\|command\\|call")
>     ;; defining symbol as function
>     ( face . "face")
>     ;; defining symbol as face
>     ( ignore . "symbol\\|program\\|property")
>     ;; ignore symbols following this context type
>     ( definition . "source \\(?:code \\)?\\(?:of\\|for\\)"))
>     ;; function definitions in files
>   "Help."
>   :type 'list
>   :version "30.1"
>   :group 'info)

I'm not sure this should be a defcustom.  Do we really expect users to
want to customize this? for what reason(s)?





^ permalink raw reply	[flat|nested] 58+ messages in thread

* bug#60587: Patch for adding links to symbols' help documentation
  2023-01-14  7:12       ` Eli Zaretskii
@ 2023-01-15 12:48         ` H. Dieter Wilhelm
  0 siblings, 0 replies; 58+ messages in thread
From: H. Dieter Wilhelm @ 2023-01-15 12:48 UTC (permalink / raw)
  To: Eli Zaretskii; +Cc: 60587, monnier

[-- Attachment #1: Type: text/plain, Size: 470 bytes --]

Could you please check the attached patch of info.el?

I'm a bit concerned about the "symbol link" face: I think it's helpful
that they're distinct from the info link face.  On the other hand the
colour is then inconsistent to links as they appear in the help buffers.

The other concern is that the info documentation from freshly installed
packages (in the current Emacs session) are still excluded from the
linking process..

I'm looking forward to your assessments


[-- Attachment #2: 0001-Provide-links-in-Info-from-symbols-to-their-help-doc.patch --]
[-- Type: text/x-diff, Size: 17275 bytes --]

From 57725936981c50cd1234d8c01c86733cc29d791f Mon Sep 17 00:00:00 2001
From: Dieter Wilhelm <dieter@duenenhof-wilhelm.de>
Date: Sun, 15 Jan 2023 13:30:45 +0100
Subject: [PATCH] Provide links in Info from symbols to their help
 documentation

---
 lisp/info.el | 383 +++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 383 insertions(+)

diff --git a/lisp/info.el b/lisp/info.el
index 035dff66e7..876addd7e1 100644
--- a/lisp/info.el
+++ b/lisp/info.el
@@ -5510,6 +5510,389 @@ info--manual-names
 					     Info-directory-list
 					     (mapcar #'car Info-suffix-list))))))))
 
+\f
+;;; Commentary:
+
+;; The code below provides links of symbols (functions, variables, and
+;; faces) within Emacs' Info viewer to their builtin help
+;; documentation.  This linking is done when symbol names in texinfo
+;; documentation (like the Emacs- and Elisp manual) are:
+
+;; 1. Quoted symbol names like `quoted-symbol' or:
+
+;; 2. Function names which are prefixed by M-x, for example M-x
+;; function-name or are quoted and prefixed, like `M-x function-name'.
+
+;; 3. Function names appearing behind the following forms, which
+;; occur, for example, in the Elisp manual:
+
+;;   -- Special Form: function-name
+;;   -- Command: ...
+;;   -- Function: ...
+;;   -- Macro: ...
+
+;; 4. And variables names behind the following text:
+
+;;   -- User Option: variable-name
+;;   -- Variable: ...
+
+;; In any case all symbol names must be known to Emacs, which means it
+;; is either a built-in, or its Lisp package is loaded for the current
+;; Emacs session, or the symbol is auto-loaded.
+
+;; You can follow the additional links with the usual Info
+;; keybindings.  The customisation variable
+;; `mouse-1-click-follows-link' is influencing the clicking behavior
+;; (and tooltips) of the links, the variable's default is 450 (milli
+;; seconds) setting it to nil means only clicking with mouse-2 is
+;; following the link (hint: Drew Adams).
+
+;; The link color of symbols - referencing their builtin documentation
+;; - is distinct from links which are referencing further Info
+;; documentation.
+
+;; Below code is checking if Info documents are relevant Elisp and
+;; Emacs related files to avoid false positives.  Please see the
+;; customization variable `info-none-emacs-or-elisp-documents'.
+
+;; The code uses mostly mechanisms from Emacs' lisp/help-mode.el file.
+
+\f
+;;; Code:
+
+(require 'button)
+(require 'cl-lib)
+(require 'help-mode)
+(require 'cl-seq)
+(require 'subr-x)
+
+(defcustom info-make-xref-flag t
+  "Non-nil means Emacs creates symbol links in info buffers.
+Please see the function `info-make-xrefs' for further
+information."
+  :type '(choice (const :tag "Create links" t)
+                 (const :tag "Do not link" nil))
+  :version "30.1"
+  :group 'info)
+
+;; Toggle on or off the linking to help documents
+(when info-make-xref-flag
+  (add-hook 'Info-selection-hook 'info-make-xrefs))
+
+(defvar info-emacs-info-dir-content nil
+  "List of file names in Emacs' info directories.
+It is used to check if the current info file `Info-current-file'
+belongs to the Emacs and Elisp context.  This variable will be
+initialised when opening the first info file.")
+
+;; Turn better into a regexp list? Hint: Stefan Monier or switch to
+;; alists with an explanation of file name?
+(defcustom info-none-emacs-or-elisp-documents
+  '("aarm2012" ; Stefan: Ada manual, Elpa archive
+    "arm2012"  ; Stefan: Ada manual
+    "sicp"   ; T.V: Structure and Interpretation of Computer Programs,
+                                        ; Melpa archive
+    )
+  "List of (known) documentation which is not related to GNU Emacs or Elisp.
+As well as documents which should not be searched for linking to
+help documentation, for more details please see
+`info-check-docu-p'.  The list must contain only the base name of
+files, without the file extension \".info\"."
+  :type '(repeat string)
+  :version "30.1"
+  :group 'info)
+
+(defun info-check-docu-p ()
+  "Check if the current info file is relevant to Emacs or Elisp.
+That means `Info-current-file' is either found in Emacs' info/
+directory or in `package-user-dir' and is not included in the
+`info-none-emacs-or-elisp-documents' list."
+  (unless info-emacs-info-dir-content
+    (info-compile-emacs-info-dir-content))
+  (let* ((ifile Info-current-file)
+         (ifi (when ifile
+                (file-name-sans-extension
+                 (file-name-nondirectory ifile))))
+         (pdir (when (boundp 'package-user-dir)
+                 (expand-file-name
+                  package-user-dir)))
+         ;; Check if checking pdir is redundant because Package adds
+         ;; info package folders to Info-directory-list anyway?
+         (ifiles info-emacs-info-dir-content)
+         (ndocu info-none-emacs-or-elisp-documents)
+         (is-info (and ifile
+                       (or (assoc-string (concat ifi ".info") ifiles)
+                           ;; the top info "dir" file
+                           (assoc-string (concat ifi ".info.gz") ifiles)
+                           ;; info files might be archived!
+                           (when pdir (string-match pdir ifile)))
+                       (not (assoc-string ifi ndocu)))))
+    (unless is-info
+      (message "No Emacs related info file: %s." ifile))
+    is-info))
+
+(defvar describe-symbol-backends)      ;from help-mode.el
+(defvar help-xref-following)           ;dito
+
+(defface info-color
+  '((t (:inherit font-lock-doc-face
+                 ;; font-lock-preprocessor-face ; similar to link face (default)
+                 ;; font-lock-builtin-face ; similar (default Emacs)
+                 ;; font-lock-function-name-face ; similar (default)
+                 ;; info-face
+                 )))
+  "Face for the `symbol' reference items in `info' nodes."
+  :group 'info-colors)
+
+;; Button types
+(define-button-type 'info
+  'link t                         ;for Info-next-reference-or-link
+  'follow-link t
+  'face 'info-color
+  'action #'info-button-action)
+
+(define-button-type 'info-function
+  :supertype 'info
+  'info-function 'describe-function
+  'info-echo (purecopy "mouse-2, RET: describe this function"))
+
+(define-button-type 'info-variable
+  :supertype 'info
+  'info-function 'describe-variable
+  'info-echo (purecopy "mouse-2, RET: describe this variable"))
+
+(define-button-type 'info-face
+  :supertype 'info
+  'info-function 'describe-face
+  'info-echo (purecopy "mouse-2, RET: describe this face"))
+
+(define-button-type 'info-symbol
+  :supertype 'info
+  'info-function #'describe-symbol
+  'info-echo (purecopy "mouse-2, RET: describe this symbol"))
+
+(define-button-type 'info-function-def
+  :supertype 'info
+  'info-function (lambda (fun &optional file type)
+                   (or file
+                       (setq file (find-lisp-object-file-name fun type)))
+                   (if (not file)
+                       (message "Unable to find defining file")
+                     (require 'find-func)
+                     (when (eq file 'C-source)
+                       (setq file
+                             (help-C-file-name (indirect-function fun) 'fun)))
+                     ;; Don't use find-function-noselect because it follows
+                     ;; aliases (which fails for built-in functions).
+                     (let ((location
+                            (find-function-search-for-symbol fun type file)))
+                       (pop-to-buffer (car location))
+                       (run-hooks 'find-function-after-hook)
+                       (if (cdr location)
+                           (goto-char (cdr location))
+                         (message "Unable to find location in file")))))
+  'info-echo (purecopy "mouse-2, RET: find function's definition"))
+
+;; Functions
+
+(defun info-compile-emacs-info-dir-content ()
+  "Build a list of file names from Emacs' info directories.
+This function fills `info-emacs-info-dir-content' with files from
+`Info-directory-list'."
+  (setq info-emacs-info-dir-content
+        (mapcar 'file-name-nondirectory ;'file-name-sans-extension
+                (directory-files
+                 (car
+                  ;; search for the main Emacs' info/ directory, when this
+                  ;; function is called Info-directory-list is already
+                  ;; initialised
+                  (cl-member "[^.]emacs" Info-directory-list :test
+                             'string-match-p))
+                 ;; don't list "." and ".."
+                 t  "[^.]$"))))
+
+(defun info-button-action (button)
+  "Call BUTTON's help function."
+  (info-do-xref nil
+                (button-get button 'info-function)
+                (button-get button 'info-args)))
+
+(defun info-do-xref (_pos function args)
+  "Call the help cross-reference function FUNCTION with args ARGS.
+Things are set up properly so that the resulting `help-buffer' has
+a proper [back] button."
+  ;; There is a reference at point.  Follow it.
+  (let ((help-xref-following nil))
+    (apply
+     function (if (eq function 'info)
+                  (append args (list (generate-new-buffer-name "*info*")))args))))
+
+(defun info-button (match-number type &rest args)
+  "Make a hyperlink for cross-reference text previously matched.
+MATCH-NUMBER is the subexpression of interest in the last matched
+regexp.  TYPE is the type of button to use.  Any remaining arguments are
+passed to the button's info-function when it is invoked.
+See `info-make-xrefs' Don't forget ARGS."
+  ;; Don't munge properties we've added, especially in some instances.
+  (unless (button-at (match-beginning match-number))
+    ;; (message "Creating button: %s." args)
+    (make-text-button (match-beginning match-number)
+                      (match-end match-number)
+                      'type type 'info-args args)))
+
+(defvar info-symbol-context
+  '(( variable . "variable\\|option")
+    ( function . "function\\|command\\|call")
+    ( face . "face")
+    ( ignore . "symbol\\|program\\|property")
+    ;; ignore symbols following this context type
+    ( definition . "source \\(?:code \\)?\\(?:of\\|for\\)"))
+  ;; function definitions in files
+  "This list helps to distinguish symbol types.
+Words in info documentation preceding a (quoted) symbol are used
+to distinguish variables, functions, faces and symbols.  The
+context information can also be used to ignore symbols because
+there is no help documentation for them.  The strings of the the
+list are becoming part of `info-symbol-regexp'.")
+
+(defvar info-symbol-regexp
+  ;; use purecopy?
+  (concat
+   "\\("                                ; Context start
+   "\\<\\("                             ; Contex type definition
+   (string-remove-suffix
+    "\\|"
+    (mapconcat
+     (lambda (x) (concat "\\(" (cdr x) "\\)\\|"))
+     info-symbol-context ""))
+   "\\)"          ; Context type definition end
+   "[ \t\n]+"     ; Separators to quoted symbols
+   "\\)?"         ; End of context
+   ;; quoted symbol
+   "['`‘]"	  ; opening quotes
+   ;; Note: Symbol starting with word-syntax character:
+   "\\(\\sw\\(\\sw\\|\\s_\\)+\\|`\\)" ; The symbol itself
+   "['’]"                             ; End quotes
+   )
+  "The regular expression for matching symbols to their help documentation.
+It is comprised of the symbol's context and the (quoted) symbol
+name.  The various groups of context regular expressions are
+matched in `info-make-xrefs' to distinct info buttons.")
+
+(defun info-check-type( type)
+  "Check if TYPE corresponds to the current search result.
+The function is used in `info-make-xrefs'."
+  (let* ((isc info-symbol-context)
+	 (n 3)                           ;embedded within 2 groups
+         (l (+ 3 (length isc))))
+    (while (and (not (eq type (caar isc) ) ) (< n l) )
+      (setq n (1+ n))
+      (setq isc (cdr isc)))
+    (match-string n)))
+
+\f
+;;;###autoload
+(defun info-make-xrefs (&optional buffer)
+  "Parse and hyperlink documentation cross-references in the given BUFFER.
+Find cross-reference information in a buffer and activate such
+cross references for selection with `help-follow'.  The current
+buffer is processed if the BUFFER argument is omitted.
+
+ Cross-references have the canonical (quoted) form `symbol-name'
+and the type of reference may be disambiguated by the preceding
+word(s) as compiled in `info-symbol-regexp'.  For example: Symbol
+names are receiving distinct variable buttons when preceeded by
+the words \"variable\" or \"option\".
+
+Variables are also detected when their names follow below form:
+
+ -- User Option: variable-name
+ -- Variable: ...
+
+Function names are also detected when prefixed by `M-x`, for
+example `M-x function-name` or are quoted and prefixed like `M-x
+function-name`.
+
+Function names are detected, as well, when appearing behind the
+following forms, which occur - for example - in the Elisp manual:
+
+ -- Special Form: function-name
+ -- Command: ...
+ -- Function: ...
+ -- Macro: ...
+
+The linking is similar to mechanisms from lisp/help.el."
+  (interactive "b")
+  (when (info-check-docu-p)
+    (with-current-buffer (or buffer (current-buffer))
+      (save-excursion
+        (goto-char (point-min))
+        (with-silent-modifications      ;hint from Stefan
+          (let ((case-fold-search t)
+                (inhibit-read-only t))
+            (with-syntax-table emacs-lisp-mode-syntax-table
+              ;; Quoted symbols
+              (save-excursion
+                (while (re-search-forward info-symbol-regexp nil t)
+                  (let* ((data (match-string (+ 3 (length info-symbol-context))))
+                         (sym (intern-soft data)))
+                    (if sym
+                        (cond
+                         ((info-check-type 'variable)
+                          (and (or (boundp sym)
+                                   (get sym 'variable-documentation))
+                               (info-button 8 'info-variable sym)))
+                         ((info-check-type 'function)
+                          (and (fboundp sym)
+                               (info-button 8 'info-function sym)))
+                         ((info-check-type 'face)
+                          (and (facep sym)
+                               (info-button 8 'info-face sym)))
+                         ((info-check-type 'ignore))
+                         ((info-check-type 'definition)
+                          (info-button 8 'info-function-def sym))
+                         ;; symbols
+                         ((cl-some (lambda (x) (funcall (nth 1 x) sym))
+                                   describe-symbol-backends)
+                          (info-button 8 'info-symbol sym)))))))
+              ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+              ;; (info "(elisp) Eval")
+              ;; Elisp manual      -- Special Form:
+              ;;                   -- Command:
+              ;;                   -- Function: function-name function
+              ;;                   -- Macro:
+              (save-excursion
+                (while (re-search-forward
+                        "-- \\(Special Form:\\|Command:\\|Function:\\|Macro:\\) "
+                        nil t)
+                  (looking-at "\\(\\sw\\|\\s_\\)+")
+                  (let ((sym (intern-soft (match-string 0))))
+                    (if (fboundp sym)
+                        (info-button 0 'info-function sym)))))
+              ;;              -- User Option:
+              ;;              -- Variable: variable-name
+              (save-excursion
+                (while (re-search-forward
+                        "-- \\(User Option:\\|Variable:\\) "
+                        nil t)
+                  (looking-at "\\(\\sw\\|\\s_\\)+")
+                  (let ((sym (intern-soft (match-string 0))))
+                    (if (boundp sym)
+                        (info-button 0 'info-variable sym)))))
+              ;; M-x prefixed functions
+              (save-excursion
+                (while (re-search-forward
+                        ;; Assume command name is only word and symbol
+                        ;; characters to get things like `use M-x foo->bar'.
+                        ;; Command required to end with word constituent
+                        ;; to avoid `.' at end of a sentence.
+                        ;; "\\<M-x\\s-+\\(\\sw\\(\\sw\\|\\s_\\)*\\sw\\)" nil t)
+                        ;; include M-x and quotes
+                        "['`‘]?M-x\\s-*\n?\\(\\sw\\(\\sw\\|\\s_\\)*\\sw\\)['’]?" nil t)
+                  (let ((sym (intern-soft (match-string 1))))
+                    (if (fboundp sym)
+                        (info-button 1 'info-function sym))))))))))))
+
 (provide 'info)
 
 ;;; info.el ends here
-- 
2.34.1


[-- Attachment #3: Type: text/plain, Size: 56 bytes --]


-- 
Best wishes
H. Dieter Wilhelm
Zwingenberg, Germany

^ permalink raw reply related	[flat|nested] 58+ messages in thread

* bug#60587: Patch for adding links to symbols' help documentation
  2023-01-07  7:38   ` Eli Zaretskii
  2023-01-08 20:06     ` H. Dieter Wilhelm
  2023-01-13 23:33     ` H. Dieter Wilhelm
@ 2023-01-17 21:53     ` H. Dieter Wilhelm
  2023-01-18 13:20       ` Eli Zaretskii
  2 siblings, 1 reply; 58+ messages in thread
From: H. Dieter Wilhelm @ 2023-01-17 21:53 UTC (permalink / raw)
  To: Eli Zaretskii; +Cc: 60587, Stefan Monnier

[-- Attachment #1: Type: text/plain, Size: 258 bytes --]

Eli Zaretskii <eliz@gnu.org> writes:
> Finally, this needs additions to the user manual and NEWS.

Do you think about Emacs' Info manual?  My feeling is that it could be
fitting to explain the additional linking capability here:

(info "(info) Help-Xref").


[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: 0001-Entry-for-Info-viewer-providing-links-from-symbols-b.patch --]
[-- Type: text/x-diff, Size: 1029 bytes --]

From 31229f536627fbb0e7dadd3f60be4d94119b9f80 Mon Sep 17 00:00:00 2001
From: Dieter Wilhelm <dieter@duenenhof-wilhelm.de>
Date: Tue, 17 Jan 2023 22:25:54 +0100
Subject: [PATCH] Entry for Info viewer providing links from symbols
 (bug#60587)

*etc/NEWS: Mention implementation
---
 etc/NEWS | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/etc/NEWS b/etc/NEWS
index 068f7a27db8..c193b59647a 100644
--- a/etc/NEWS
+++ b/etc/NEWS
@@ -165,6 +165,14 @@ the new argument non-nil, it will use a new buffer instead.
 Interactively, invoke 'eww-open-file' with a prefix argument to
 activate this behavior.
 
+** Info
+
+*** Info viewer provides now links from symbols to their help documentation.
+Links from quoted `symbol' names, like names of variables, functions
+and faces, are pointing to their *Help* documentation. If you want to
+disable such links - in addition to the regular Info cross references
+- you can set the variable `info-make-xref-flag' to nil.
+
 \f
 * New Modes and Packages in Emacs 30.1
 
-- 
2.34.1


[-- Attachment #3: Type: text/plain, Size: 56 bytes --]


-- 
Best wishes
H. Dieter Wilhelm
Zwingenberg, Germany

^ permalink raw reply related	[flat|nested] 58+ messages in thread

* bug#60587: Patch for adding links to symbols' help documentation
  2023-01-17 21:53     ` H. Dieter Wilhelm
@ 2023-01-18 13:20       ` Eli Zaretskii
  2023-01-20 21:09         ` H. Dieter Wilhelm
  0 siblings, 1 reply; 58+ messages in thread
From: Eli Zaretskii @ 2023-01-18 13:20 UTC (permalink / raw)
  To: H. Dieter Wilhelm; +Cc: 60587, monnier

> From: "H. Dieter Wilhelm" <dieter@duenenhof-wilhelm.de>
> Cc: Stefan Monnier <monnier@iro.umontreal.ca>,  60587@debbugs.gnu.org
> Date: Tue, 17 Jan 2023 22:53:23 +0100
> 
> Eli Zaretskii <eliz@gnu.org> writes:
> > Finally, this needs additions to the user manual and NEWS.
> 
> Do you think about Emacs' Info manual?  My feeling is that it could be
> fitting to explain the additional linking capability here:
> 
> (info "(info) Help-Xref").

No, the info.info manual is not what I had in mind.  I meant the Emacs
manual.

I think a good place is to mention this feature in the "Misc Help"
section.

> +*** Info viewer provides now links from symbols to their help documentation.
> +Links from quoted `symbol' names, like names of variables, functions
> +and faces, are pointing to their *Help* documentation. If you want to
> +disable such links - in addition to the regular Info cross references
> +- you can set the variable `info-make-xref-flag' to nil.

First, please leave 2 spaces between sentences, and use "--" for a
dash.

More importantly, "pointing to help documentation" is confusing: what
exactly is "help documentation" here, and how does an Info manual
"point" there.

I think you should instead say that these symbols are made into
buttons that can be used to display the documentation strings of the
functions/variables.  Or something to that effect.

Thanks.





^ permalink raw reply	[flat|nested] 58+ messages in thread

* bug#60587: Patch for adding links to symbols' help documentation
  2023-01-18 13:20       ` Eli Zaretskii
@ 2023-01-20 21:09         ` H. Dieter Wilhelm
  2023-01-20 21:59           ` Drew Adams
                             ` (2 more replies)
  0 siblings, 3 replies; 58+ messages in thread
From: H. Dieter Wilhelm @ 2023-01-20 21:09 UTC (permalink / raw)
  To: Eli Zaretskii; +Cc: 60587, monnier

[-- Attachment #1: Type: text/plain, Size: 455 bytes --]

Eli Zaretskii <eliz@gnu.org> writes:

> I think a good place is to mention this feature in the "Misc Help"
> section.

Could you please check if below formulation is better fitting?

Unfortunately I also need to investigate the code anew.  Yesterday I
realised a regression starting with Emacs-29!  `Tab' and `S-Tab' aren't
working any longer for Info references.  (E.g. the `Tab' keybinding is
switched from `Info-next-reference' to `forward-button'..)


[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: 0001-Documentation-of-Info-providing-buttons-on-quoted-sy.patch --]
[-- Type: text/x-diff, Size: 2157 bytes --]

From fa7c61466157a580b17d15f989e1b825ba4c860a Mon Sep 17 00:00:00 2001
From: Dieter Wilhelm <dieter@duenenhof-wilhelm.de>
Date: Tue, 17 Jan 2023 22:25:54 +0100
Subject: [PATCH] Documentation of Info providing buttons on quoted symbols
 (bug#60587)

*etc/NEWS: Mention implementation
*doc/emacs/help.texi: Describe implementation
---
 doc/emacs/help.texi |  9 +++++++++
 etc/NEWS            | 11 +++++++++++
 2 files changed, 20 insertions(+)

diff --git a/doc/emacs/help.texi b/doc/emacs/help.texi
index 2513e6be271..781b2bf1ab4 100644
--- a/doc/emacs/help.texi
+++ b/doc/emacs/help.texi
@@ -653,6 +653,15 @@ Misc Help
 K @var{key}}, described above, enter Info and go straight to the
 documentation of @var{function} or @var{key}.
 
+  The commands @kbd{C-h f} and @kbd{C-h v}, also described above
+(@xref{Name Help}), in an Info buffer can be replaced by @kbd{Ret} or
+@kbd{mouse-1} on quoted symbol names.  For example, the quoted name
+@code{info-other-window} is made into a button which shows the
+function's documentation string in another window in the @file{*Help*}
+buffer.  Such quoted symbols (variables, functions and face names) are
+highlighted by a distinct face and can be reached, as the Info
+references, with @kbd{Tab} and @kbd{S-Tab}.
+
 @kindex C-h S
 @findex info-lookup-symbol
   When editing a program, if you have an Info version of the manual
diff --git a/etc/NEWS b/etc/NEWS
index fc8a3ac66a0..f9ea0084cb5 100644
--- a/etc/NEWS
+++ b/etc/NEWS
@@ -174,6 +174,17 @@ the new argument non-nil, it will use a new buffer instead.
 Interactively, invoke 'eww-open-file' with a prefix argument to
 activate this behavior.
 
+** Info
+
++++
+*** Info-mode provides buttons on symbols showing their documentation string.
+Quoted `symbols', like names of variables, functions or face names,
+are made into buttons which can display the respective documentation
+strings.  These strings are presented in *Help* buffers in another
+window.  Such buttons are working independently of the regular Info
+cross references and can be disabled with setting
+`info-make-xref-flag' to nil.
+
 \f
 * New Modes and Packages in Emacs 30.1
 
-- 
2.34.1


[-- Attachment #3: Type: text/plain, Size: 56 bytes --]


-- 
Best wishes
H. Dieter Wilhelm
Zwingenberg, Germany

^ permalink raw reply related	[flat|nested] 58+ messages in thread

* bug#60587: Patch for adding links to symbols' help documentation
  2023-01-20 21:09         ` H. Dieter Wilhelm
@ 2023-01-20 21:59           ` Drew Adams
  2023-01-20 23:32           ` Stefan Monnier via Bug reports for GNU Emacs, the Swiss army knife of text editors
  2023-01-21  8:21           ` Eli Zaretskii
  2 siblings, 0 replies; 58+ messages in thread
From: Drew Adams @ 2023-01-20 21:59 UTC (permalink / raw)
  To: H. Dieter Wilhelm, Eli Zaretskii
  Cc: 60587@debbugs.gnu.org, monnier@iro.umontreal.ca

Caveat: I'm not following this thread; sorry.

A quick look at your patch shows this:

  The commands @kbd{C-h f} and @kbd{C-h v}, also described above
  +(@xref{Name Help}), in an Info buffer can be replaced by @kbd{Ret} or
  +@kbd{mouse-1} on quoted symbol names.

I think it's wrong to say that `mouse-1' does that.
At least I hope it's wrong, and that you correctly
used the behavior that `mouse-1' only does that if
option `mouse-1-click-follows-link' is non-nil.

I also disagree with calling these "buttons".  I
think that Info calls them "links".  E.g., in
(info)Help-Xref you see this:

  Such a cross reference looks like this:
  *Note Overview of Texinfo: (texinfo)Top.
  (After following this link, type 'l' to
                        ^^^^
  get back to this node.)

And just the name of the above-mentioned option
should make clear that these things are presented
to users as "links", not "buttons".  Its doc says:

  Non-nil means that clicking Mouse-1 on a link
                                           ^^^^
  follows the link.
              ^^^^

The active bit of text is referred to as a "link",
and so is the relation between this source location
and the destination reached.  You click a link to
follow that link to its destination.

Elisp may refer to creating a "button" for this,
but for users we should call them "links", not
"buttons".





^ permalink raw reply	[flat|nested] 58+ messages in thread

* bug#60587: Patch for adding links to symbols' help documentation
  2023-01-20 21:09         ` H. Dieter Wilhelm
  2023-01-20 21:59           ` Drew Adams
@ 2023-01-20 23:32           ` Stefan Monnier via Bug reports for GNU Emacs, the Swiss army knife of text editors
  2023-01-22 13:00             ` H. Dieter Wilhelm
  2023-01-21  8:21           ` Eli Zaretskii
  2 siblings, 1 reply; 58+ messages in thread
From: Stefan Monnier via Bug reports for GNU Emacs, the Swiss army knife of text editors @ 2023-01-20 23:32 UTC (permalink / raw)
  To: H. Dieter Wilhelm; +Cc: Eli Zaretskii, 60587

> Unfortunately I also need to investigate the code anew.  Yesterday I
> realised a regression starting with Emacs-29!  `Tab' and `S-Tab' aren't
> working any longer for Info references.  (E.g. the `Tab' keybinding is
> switched from `Info-next-reference' to `forward-button'..)

My crystal ball suggests that some code somewhere binds
`forward-button` to the "tab" event rather than to the "TAB" event.
"tab" should usually stay unbound (it is then remapped to "TAB" by
`function-key-map`).


        Stefan






^ permalink raw reply	[flat|nested] 58+ messages in thread

* bug#60587: Patch for adding links to symbols' help documentation
  2023-01-20 21:09         ` H. Dieter Wilhelm
  2023-01-20 21:59           ` Drew Adams
  2023-01-20 23:32           ` Stefan Monnier via Bug reports for GNU Emacs, the Swiss army knife of text editors
@ 2023-01-21  8:21           ` Eli Zaretskii
  2023-01-21 20:27             ` H. Dieter Wilhelm
  2023-01-25 21:29             ` H. Dieter Wilhelm
  2 siblings, 2 replies; 58+ messages in thread
From: Eli Zaretskii @ 2023-01-21  8:21 UTC (permalink / raw)
  To: H. Dieter Wilhelm; +Cc: 60587, monnier

> From: "H. Dieter Wilhelm" <dieter@duenenhof-wilhelm.de>
> Cc: monnier@iro.umontreal.ca,  60587@debbugs.gnu.org
> Date: Fri, 20 Jan 2023 22:09:03 +0100
> 
> Eli Zaretskii <eliz@gnu.org> writes:
> 
> > I think a good place is to mention this feature in the "Misc Help"
> > section.
> 
> Could you please check if below formulation is better fitting?

Yes, but it "needs some work", see below.

> Unfortunately I also need to investigate the code anew.  Yesterday I
> realised a regression starting with Emacs-29!  `Tab' and `S-Tab' aren't
> working any longer for Info references.  (E.g. the `Tab' keybinding is
> switched from `Info-next-reference' to `forward-button'..)

So I guess you will be submitting a new patch soon?

> --- a/doc/emacs/help.texi
> +++ b/doc/emacs/help.texi
> @@ -653,6 +653,15 @@ Misc Help
>  K @var{key}}, described above, enter Info and go straight to the
>  documentation of @var{function} or @var{key}.
>  
> +  The commands @kbd{C-h f} and @kbd{C-h v}, also described above
> +(@xref{Name Help}), in an Info buffer can be replaced by @kbd{Ret} or
> +@kbd{mouse-1} on quoted symbol names.  For example, the quoted name
> +@code{info-other-window} is made into a button which shows the
> +function's documentation string in another window in the @file{*Help*}
> +buffer.  Such quoted symbols (variables, functions and face names) are
> +highlighted by a distinct face and can be reached, as the Info
> +references, with @kbd{Tab} and @kbd{S-Tab}.

I think the first sentence should be rewritten as describing a
separate feature, not "the same as" something else.  Just say that
symbols are converted into buttons that lead to their doc strings.

Also, the option which controls this should be mentioned and indexed.

> +** Info
> +
> ++++
> +*** Info-mode provides buttons on symbols showing their documentation string.
> +Quoted `symbols', like names of variables, functions or face names,
> +are made into buttons which can display the respective documentation
> +strings.  These strings are presented in *Help* buffers in another
> +window.  Such buttons are working independently of the regular Info
> +cross references and can be disabled with setting
> +`info-make-xref-flag' to nil.

This is OK.

Thanks.





^ permalink raw reply	[flat|nested] 58+ messages in thread

* bug#60587: Patch for adding links to symbols' help documentation
  2023-01-21  8:21           ` Eli Zaretskii
@ 2023-01-21 20:27             ` H. Dieter Wilhelm
  2023-01-22  6:00               ` Eli Zaretskii
  2023-01-25 21:29             ` H. Dieter Wilhelm
  1 sibling, 1 reply; 58+ messages in thread
From: H. Dieter Wilhelm @ 2023-01-21 20:27 UTC (permalink / raw)
  To: Eli Zaretskii; +Cc: 60587, monnier

Eli Zaretskii <eliz@gnu.org> writes:

>> Unfortunately I also need to investigate the code anew.  Yesterday I
>> realised a regression starting with Emacs-29!  `Tab' and `S-Tab' aren't
>> working any longer for Info references.  (E.g. the `Tab' keybinding is
>> switched from `Info-next-reference' to `forward-button'..)
>
> So I guess you will be submitting a new patch soon?

Yes, I hope with the help of Stefan's crystal .., ahem promising hint,
soon.

>> --- a/doc/emacs/help.texi
>> +++ b/doc/emacs/help.texi
>> ...
> I think the first sentence should be rewritten as describing a
> separate feature, not "the same as" something else.  Just say that
> symbols are converted into buttons that lead to their doc strings.

That's clearer, I'll do that.

Shouldn't I address the concern of Drew, as well?  That a "button" is a
certain technical implementation of linking which might not be known by
the reader.  Maybe a term like "link button" or "link-button" conveys -
at the same time - the well known concept and correct technique,
different from an Info link (or "cross reference")?

> Also, the option which controls this should be mentioned and indexed.

Ah, of course!

Thanks for your suggestions

-- 
Best wishes
H. Dieter Wilhelm
Zwingenberg, Germany





^ permalink raw reply	[flat|nested] 58+ messages in thread

* bug#60587: Patch for adding links to symbols' help documentation
  2023-01-21 20:27             ` H. Dieter Wilhelm
@ 2023-01-22  6:00               ` Eli Zaretskii
  2023-01-22 22:09                 ` Drew Adams
  0 siblings, 1 reply; 58+ messages in thread
From: Eli Zaretskii @ 2023-01-22  6:00 UTC (permalink / raw)
  To: H. Dieter Wilhelm; +Cc: 60587, monnier

> From: "H. Dieter Wilhelm" <dieter@duenenhof-wilhelm.de>
> Cc: monnier@iro.umontreal.ca,  60587@debbugs.gnu.org
> Date: Sat, 21 Jan 2023 21:27:46 +0100
> 
> Eli Zaretskii <eliz@gnu.org> writes:
> 
> >> Unfortunately I also need to investigate the code anew.  Yesterday I
> >> realised a regression starting with Emacs-29!  `Tab' and `S-Tab' aren't
> >> working any longer for Info references.  (E.g. the `Tab' keybinding is
> >> switched from `Info-next-reference' to `forward-button'..)
> >
> > So I guess you will be submitting a new patch soon?
> 
> Yes, I hope with the help of Stefan's crystal .., ahem promising hint,
> soon.

TIA

> Shouldn't I address the concern of Drew, as well?  That a "button" is a
> certain technical implementation of linking which might not be known by
> the reader.  Maybe a term like "link button" or "link-button" conveys -
> at the same time - the well known concept and correct technique,
> different from an Info link (or "cross reference")?

I think "button" is problematic, and have no idea why Drew thinks we
should use another term here.  The code does insert buttons, right?
If the user types "M-x describe-text-properties RET", will he/she see
that there's a button at point?





^ permalink raw reply	[flat|nested] 58+ messages in thread

* bug#60587: Patch for adding links to symbols' help documentation
  2023-01-20 23:32           ` Stefan Monnier via Bug reports for GNU Emacs, the Swiss army knife of text editors
@ 2023-01-22 13:00             ` H. Dieter Wilhelm
  0 siblings, 0 replies; 58+ messages in thread
From: H. Dieter Wilhelm @ 2023-01-22 13:00 UTC (permalink / raw)
  To: Stefan Monnier; +Cc: Eli Zaretskii, 60587

Stefan Monnier <monnier@iro.umontreal.ca> writes:

>> Unfortunately I also need to investigate the code anew.  Yesterday I
>> realised a regression starting with Emacs-29!  `Tab' and `S-Tab' aren't
>> working any longer for Info references.  (E.g. the `Tab' keybinding is
>> switched from `Info-next-reference' to `forward-button'..)

Above information is, in fact, true but too narrow, since the
"switching" of keybindings is not occurring in general but only
happening when point sits directly on a button.  In regular Info text
either links, buttons and Info references, can still be reached by Tab
(or S-Tab).

> My crystal ball suggests that some code somewhere binds
> `forward-button` to the "tab" event rather than to the "TAB" event.
> "tab" should usually stay unbound (it is then remapped to "TAB" by
> `function-key-map`).

Poked around in button.el, info.el and help.el but couldn't find any
"tab" event binding (only "TAB").

But I think, I found the reason why it appears since Emacs-29, when
commenting out the following line in lisp/button.el the keybindings are
working as before Emacs-29:


    (defvar-keymap button-buffer-map
      :doc "Keymap useful for buffers containing buttons.
    Mode-specific keymaps may want to use this as their parent keymap."
      "TAB" #'forward-button
      "ESC TAB" #'backward-button
      "<backtab>" #'backward-button)

    (defvar-keymap button-map
      :doc "Keymap used by buttons."
-->;; :parent button-buffer-map
    "RET" #'push-button
      "<mouse-2>" #'push-button
      "<follow-link>" 'mouse-face
      ;; FIXME: You'd think that for keymaps coming from text-properties on the
      ;; mode-line or header-line, the `mode-line' or `header-line' prefix
      ;; shouldn't be necessary!
      "<mode-line> <mouse-2>" #'push-button
      "<header-line> <mouse-2>" #'push-button)

It seems to me that this is not a regression but some additional
functionality of Emacs.  I've yet to figure out how to deal with the
enhanced keymap of buttons..

-- 
Thank you for your interest

      Dieter

Best wishes
H. Dieter Wilhelm
Zwingenberg, Germany





^ permalink raw reply	[flat|nested] 58+ messages in thread

* bug#60587: Patch for adding links to symbols' help documentation
  2023-01-22  6:00               ` Eli Zaretskii
@ 2023-01-22 22:09                 ` Drew Adams
  2023-01-23 12:14                   ` Eli Zaretskii
  0 siblings, 1 reply; 58+ messages in thread
From: Drew Adams @ 2023-01-22 22:09 UTC (permalink / raw)
  To: Eli Zaretskii, H. Dieter Wilhelm
  Cc: 60587@debbugs.gnu.org, monnier@iro.umontreal.ca

> > Shouldn't I address the concern of Drew, as well?  That a "button" is a
> > certain technical implementation of linking which might not be known by
                      ^^^^^^^^^^^^^^^^^^^^^^
> > the reader.  Maybe a term like "link button" or "link-button" conveys -
> > at the same time - the well known concept and correct technique,
> > different from an Info link (or "cross reference")?
> 
> I think "button" is problematic, 

Did you perhaps mean _not_ problematic?  I said it's
problematic, and you don't seem to agree with me.
Or maybe you meant only "button" in "link button".
In that case, I agree with you.  We should just say
"link".

> and have no idea why Drew thinks we
> should use another term here.

Another term than "button"?  Or "link-button"?

Drew thinks we should use the same standard term we
use everywhere - including in Info: for users it's a
link, not a button.

It may be implemented in Elisp by something Elisp
calls a "button" (not a great name, but not important
here) - but that's now what Emacs calls it in
communicating with users.  In particular, it's not
how the Info docs refer to it.  For users it's a link.

> The code does insert buttons, right?

The code implements links by inserting what Elisp
calls "buttons", yes.  Is how the code implements
links what's important here?

> If the user types "M-x describe-text-properties RET",
> will he/she see that there's a button at point?

Dunno what Dieter's code shows for that.  But this is
what doing that on an xref link in Info shows:

There are text properties here:
  font-lock-face       info-xref
  fontified            t
  help-echo            [Show]
  mouse-face           highlight

I wouldn't say that a user is told there's a button
there.





^ permalink raw reply	[flat|nested] 58+ messages in thread

* bug#60587: Patch for adding links to symbols' help documentation
  2023-01-22 22:09                 ` Drew Adams
@ 2023-01-23 12:14                   ` Eli Zaretskii
  2023-01-23 16:16                     ` Drew Adams
  0 siblings, 1 reply; 58+ messages in thread
From: Eli Zaretskii @ 2023-01-23 12:14 UTC (permalink / raw)
  To: Drew Adams; +Cc: dieter, 60587, monnier

> From: Drew Adams <drew.adams@oracle.com>
> CC: "60587@debbugs.gnu.org" <60587@debbugs.gnu.org>,
>         "monnier@iro.umontreal.ca" <monnier@iro.umontreal.ca>
> Date: Sun, 22 Jan 2023 22:09:28 +0000
> 
> > > Shouldn't I address the concern of Drew, as well?  That a "button" is a
> > > certain technical implementation of linking which might not be known by
>                       ^^^^^^^^^^^^^^^^^^^^^^
> > > the reader.  Maybe a term like "link button" or "link-button" conveys -
> > > at the same time - the well known concept and correct technique,
> > > different from an Info link (or "cross reference")?
> > 
> > I think "button" is problematic, 
> 
> Did you perhaps mean _not_ problematic?

Yes, I don't think "button" is problematic.

> Drew thinks we should use the same standard term we
> use everywhere - including in Info: for users it's a
> link, not a button.

We use "buttons" as well as "hyperlinks".  See, e.g., the node "Mouse
References" in the user manual, which basically describes the facility
Dieter intends to use.

> > If the user types "M-x describe-text-properties RET",
> > will he/she see that there's a button at point?
> 
> Dunno what Dieter's code shows for that.  But this is
> what doing that on an xref link in Info shows:
> 
> There are text properties here:
>   font-lock-face       info-xref
>   fontified            t
>   help-echo            [Show]
>   mouse-face           highlight
> 
> I wouldn't say that a user is told there's a button
> there.

I meant the hyperlinks in the *Help* buffer.





^ permalink raw reply	[flat|nested] 58+ messages in thread

* bug#60587: Patch for adding links to symbols' help documentation
  2023-01-23 12:14                   ` Eli Zaretskii
@ 2023-01-23 16:16                     ` Drew Adams
  0 siblings, 0 replies; 58+ messages in thread
From: Drew Adams @ 2023-01-23 16:16 UTC (permalink / raw)
  To: Eli Zaretskii
  Cc: dieter@duenenhof-wilhelm.de, 60587@debbugs.gnu.org,
	monnier@iro.umontreal.ca

> I don't think "button" is problematic.
> 
> > Drew thinks we should use the same standard term we
> > use everywhere - including in Info: for users it's a
> > link, not a button.
> 
> We use "buttons" as well as "hyperlinks".  See, e.g., the node "Mouse
> References" in the user manual, which basically describes the facility
> Dieter intends to use.

You're right - that node speaks of `"buttons", or
"hyperlinks"'.  And node `Scroll Bars' speaks of
"the scroll bar's up and down buttons".

I think such terminology is old - early/mid 90s.
"Hyperlinks" is OK, but in general they're just
referred to as "links" now, I think.  That is, since
the Internet and web took hold in a general way.

The UI things that actually look like buttons, can
reasonably be called "buttons", especially things
that perform some _action_ other than moving to a
different text location.  I think this applies to
icons in the tool bar and fields in the mode-line
and header line, and it applies to some of the spots
in Customize.  I don't think it's the best term to
use for text links.

That there are some remaining places where Emacs or
Elisp still refers to links as "buttons" isn't a
reason to continue using "button" for links, in new
doc or when updating existing doc (IMO).  My advice
is to progressively move away from such a use of
"button" when doing that.

But if you prefer to continue with "button", so be it.

> > > If the user types "M-x describe-text-properties RET",
> > > will he/she see that there's a button at point?
> I meant the hyperlinks in the *Help* buffer.

I see, thanks.  Yes, I see that - e.g.:

There are text properties here:
  button               (t)
  category             help-symbol-button
  help-args            (symbol-nearest-point)

However, again, this kind of help (showing text
properties) essentially exposes _implementation_
names, so that's no surprise.  Yes, Elisp has
things called "buttons".

Nothing wrong with help doing this, of course.
But that's not a reason why the user doc (e.g.
Emacs manual) should call links there "buttons".

The current change is for Info.  What terminology
does the Info manual use?  Searching for "button"
shows that the only occurrences are for mouse
buttons (physical buttons).  And there are lots
of occurrences of "link".  _All_ mention of what
we're talking about uses "link", never "button".
That's how Info talks about itself and its parts.

Here's a typical use of both terms from the Info
manual.  "Link" is the thing you see and click
(or hit `RET' on).  "Button" is a physical mouse
part that you click.

 >> Now type 'n', or click the middle mouse button
    on the 'Next' link, to visit the next node.

But if you prefer "buttons", "buttons" it is.
Users will understand, either way.





^ permalink raw reply	[flat|nested] 58+ messages in thread

* bug#60587: Patch for adding links to symbols' help documentation
  2023-01-21  8:21           ` Eli Zaretskii
  2023-01-21 20:27             ` H. Dieter Wilhelm
@ 2023-01-25 21:29             ` H. Dieter Wilhelm
  2023-01-25 22:24               ` Drew Adams
  2023-01-26 10:37               ` Eli Zaretskii
  1 sibling, 2 replies; 58+ messages in thread
From: H. Dieter Wilhelm @ 2023-01-25 21:29 UTC (permalink / raw)
  To: Eli Zaretskii; +Cc: 60587, monnier

[-- Attachment #1: Type: text/plain, Size: 758 bytes --]

Eli Zaretskii <eliz@gnu.org> writes:

>> Unfortunately I also need to investigate the code anew.  Yesterday I
>> realised a regression starting with Emacs-29!  `Tab' and `S-Tab' aren't
>> working any longer for Info references.  (E.g. the `Tab' keybinding is
>> switched from `Info-next-reference' to `forward-button'..)
>
> So I guess you will be submitting a new patch soon?

Below it is (based on a recent master commit).

> I think the first sentence should be rewritten as describing a
> separate feature, not "the same as" something else.  Just say that
> symbols are converted into buttons that lead to their doc strings.
>
> Also, the option which controls this should be mentioned and indexed.

Please have a look at a further documentation patch.


[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: 0001-Documentation-of-Info-providing-buttons-on-quoted-sy.patch --]
[-- Type: text/x-diff, Size: 2382 bytes --]

From 2e1f604c0923d39bbbc9314903622b92b3118830 Mon Sep 17 00:00:00 2001
From: Dieter Wilhelm <dieter@duenenhof-wilhelm.de>
Date: Mon, 23 Jan 2023 21:13:54 +0100
Subject: [PATCH] Documentation of Info providing buttons on quoted symbols
 (bug#60587)

*etc/NEWS: Mention implementation
*doc/emacs/help.texi: Describe implementation and how to switch off
 button creation
---
 doc/emacs/help.texi | 13 +++++++++++++
 etc/NEWS            | 11 +++++++++++
 2 files changed, 24 insertions(+)

diff --git a/doc/emacs/help.texi b/doc/emacs/help.texi
index 2513e6be271..02b8962c360 100644
--- a/doc/emacs/help.texi
+++ b/doc/emacs/help.texi
@@ -653,6 +653,19 @@ Misc Help
 K @var{key}}, described above, enter Info and go straight to the
 documentation of @var{function} or @var{key}.
 
+  In Info buffers quoted symbol names are made into buttons which show
+the symbols' help documentation when typing @key{RET} or clicking
+@kbd{mouse-2} or @kbd{mouse-1} on it.  For example, the quoted name
+@code{info-other-window} is made into a button which shows the
+function's documentation string in another window, in the
+@file{*Help*} buffer.  Such quoted symbols (variables, functions and
+face names) are highlighted by a distinct face and can be reached, as
+the Info manual references, with @key{TAB} and @kbd{S-Tab}.
+
+@vindex info-make-xref-flag
+  If you want to prohibit the button creation for Info buffers, you
+can set @code{info-make-xref-flag} to @code{nil}.
+
 @kindex C-h S
 @findex info-lookup-symbol
   When editing a program, if you have an Info version of the manual
diff --git a/etc/NEWS b/etc/NEWS
index 5b8ab06086c..c55d39baf0c 100644
--- a/etc/NEWS
+++ b/etc/NEWS
@@ -195,6 +195,17 @@ This command adds a docstring comment to the current defun.  If a
 comment already exists, point is only moved to the comment.  It is
 bound to 'C-c C-d' in 'go-ts-mode'.
 
+** Info
+
++++
+*** Info-mode provides buttons on symbols showing their documentation string.
+Quoted `symbols', like names of variables, functions or face names,
+are made into buttons which can display the respective documentation
+strings.  These strings are presented in *Help* buffers in another
+window.  Such buttons are working independently of the regular Info
+cross references and can be disabled with setting
+`info-make-xref-flag' to nil.
+
 \f
 * New Modes and Packages in Emacs 30.1
 
-- 
2.34.1


[-- Attachment #3: 0001-Info-providing-buttons-on-quoted-symbols-bug-60587.patch --]
[-- Type: text/x-diff, Size: 17806 bytes --]

From f0d2f389d8b1967a2b14e297069aedad06e1c7e8 Mon Sep 17 00:00:00 2001
From: Dieter Wilhelm <dieter@duenenhof-wilhelm.de>
Date: Wed, 25 Jan 2023 22:00:57 +0100
Subject: [PATCH] Info providing buttons on quoted symbols (bug#60587)

*lisp/info.el
---
 lisp/info.el | 397 +++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 397 insertions(+)

diff --git a/lisp/info.el b/lisp/info.el
index 035dff66e75..48ce78ac1e2 100644
--- a/lisp/info.el
+++ b/lisp/info.el
@@ -5510,6 +5510,403 @@ info--manual-names
 					     Info-directory-list
 					     (mapcar #'car Info-suffix-list))))))))
 
+\f
+;;; Commentary:
+
+;; The code below provides links of symbols (functions, variables, and
+;; faces) within Emacs' Info viewer to their builtin help
+;; documentation.  This linking is done when symbol names in texinfo
+;; documentation (like the Emacs- and Elisp manual) are:
+
+;; 1. Quoted symbol names like `quoted-symbol' or:
+
+;; 2. Function names which are prefixed by M-x, for example M-x
+;; function-name or are quoted and prefixed, like `M-x function-name'.
+
+;; 3. Function names appearing behind the following forms, which
+;; occur, for example, in the Elisp manual:
+
+;;   -- Special Form: function-name
+;;   -- Command: ...
+;;   -- Function: ...
+;;   -- Macro: ...
+
+;; 4. And variables names behind the following text:
+
+;;   -- User Option: variable-name
+;;   -- Variable: ...
+
+;; In any case all symbol names must be known to Emacs, which means it
+;; is either a built-in, or its Lisp package is loaded for the current
+;; Emacs session, or the symbol is auto-loaded.
+
+;; You can follow the additional links with the usual Info
+;; keybindings.  The customisation variable
+;; `mouse-1-click-follows-link' is influencing the clicking behavior
+;; (and tooltips) of the links, the variable's default is 450 (milli
+;; seconds) setting it to nil means only clicking with mouse-2 is
+;; following the link (hint: Drew Adams).
+
+;; The link color of symbols - referencing their builtin documentation
+;; - is distinct from links which are referencing further Info
+;; documentation.
+
+;; Below code is checking if Info documents are relevant Elisp and
+;; Emacs related files to avoid false positives.  Please see the
+;; customization variable `info-none-emacs-or-elisp-documents'.
+
+;; The code uses mostly mechanisms from Emacs' lisp/help-mode.el file.
+
+\f
+;;; Code:
+
+(require 'button)
+(require 'cl-lib)
+(require 'help-mode)
+(require 'cl-seq)
+(require 'subr-x)
+
+(defcustom info-make-xref-flag t
+  "Non-nil means Emacs creates symbol links in info buffers.
+Please see the function `info-make-xrefs' for further
+information."
+  :type '(choice (const :tag "Create links" t)
+                 (const :tag "Do not link" nil))
+  :version "30.1"
+  :group 'info)
+
+;; Toggle on or off the linking to help documents
+(when info-make-xref-flag
+  (add-hook 'Info-selection-hook 'info-make-xrefs))
+
+(defvar info-emacs-info-dir-content nil
+  "List of file names in Emacs' info directories.
+It is used to check if the current info file `Info-current-file'
+belongs to the Emacs and Elisp context.  This variable will be
+initialised when opening the first info file.")
+
+;; Turn better into a regexp list? Hint: Stefan Monier or switch to
+;; alists with an explanation of file name?
+(defcustom info-none-emacs-or-elisp-documents
+  '("aarm2012" ; Stefan: Ada manual, Elpa archive
+    "arm2012"  ; Stefan: Ada manual
+    "sicp"   ; T.V: Structure and Interpretation of Computer Programs,
+                                        ; Melpa archive
+    )
+  "List of (known) documentation which is not related to GNU Emacs or Elisp.
+As well as documents which should not be searched for linking to
+help documentation, for more details please see
+`info-check-docu-p'.  The list must contain only the base name of
+files, without the file extension \".info\"."
+  :type '(repeat string)
+  :version "30.1"
+  :group 'info)
+
+(defun info-check-docu-p ()
+  "Check if the current info file is relevant to Emacs or Elisp.
+That means `Info-current-file' is either found in Emacs' info/
+directory or in `package-user-dir' and is not included in the
+`info-none-emacs-or-elisp-documents' list."
+  (unless info-emacs-info-dir-content
+    (info-compile-emacs-info-dir-content))
+  (let* ((ifile Info-current-file)
+         (ifi (when ifile
+                (file-name-sans-extension
+                 (file-name-nondirectory ifile))))
+         (pdir (when (boundp 'package-user-dir)
+                 (expand-file-name
+                  package-user-dir)))
+         ;; Check if checking pdir is redundant because Package adds
+         ;; info package folders to Info-directory-list anyway?
+         (ifiles info-emacs-info-dir-content)
+         (ndocu info-none-emacs-or-elisp-documents)
+         (is-info (and ifile
+                       (or (assoc-string (concat ifi ".info") ifiles)
+                           ;; the top info "dir" file
+                           (assoc-string (concat ifi ".info.gz") ifiles)
+                           ;; info files might be archived!
+                           (when pdir (string-match pdir ifile)))
+                       (not (assoc-string ifi ndocu)))))
+    (unless is-info
+      (message "No Emacs related info file: %s." ifile))
+    is-info))
+
+(defvar describe-symbol-backends)      ;from help-mode.el
+(defvar help-xref-following)           ;dito
+
+;; customisation candidate
+(defface info-color
+  '((t (:inherit font-lock-doc-face
+                 ;; font-lock-preprocessor-face ; similar to link face (default)
+                 ;; font-lock-builtin-face ; similar (default Emacs)
+                 ;; font-lock-function-name-face ; similar (default)
+                 ;; info-face
+                 )))
+  "Face for all `symbol' references in `Info' nodes."
+  :group 'info-colors)
+
+(defvar-keymap info-button-map
+  :doc "Keymap used by buttons in Info buffers."
+  "RET" #'push-button
+  "<mouse-2>" #'push-button
+  "<follow-link>" 'mouse-face
+  ;; FIXME: You'd think that for keymaps coming from text-properties on the
+  ;; mode-line or header-line, the `mode-line' or `header-line' prefix
+  ;; shouldn't be necessary!
+  "<mode-line> <mouse-2>" #'push-button
+  "<header-line> <mouse-2>" #'push-button)
+
+;; Button types
+(define-button-type 'info
+  'link t
+  'follow-link t
+  'face 'info-color
+  'keymap info-button-map
+  'action #'info-button-action)
+
+(define-button-type 'info-function
+  :supertype 'info
+  'info-function 'describe-function
+  'help-echo (purecopy "mouse-2, RET: describe this function"))
+
+(define-button-type 'info-variable
+  :supertype 'info
+  'info-function 'describe-variable
+  'help-echo (purecopy "mouse-2, RET: describe this variable"))
+
+(define-button-type 'info-face
+  :supertype 'info
+  'info-function 'describe-face
+  'help-echo (purecopy "mouse-2, RET: describe this face"))
+
+(define-button-type 'info-symbol
+  :supertype 'info
+  'info-function #'describe-symbol
+  'help-echo (purecopy "mouse-2, RET: describe this symbol"))
+
+(define-button-type 'info-function-def
+  :supertype 'info
+  'info-function (lambda (fun &optional file type)
+                   (or file
+                       (setq file (find-lisp-object-file-name fun type)))
+                   (if (not file)
+                       (message "Unable to find defining file")
+                     (require 'find-func)
+                     (when (eq file 'C-source)
+                       (setq file
+                             (help-C-file-name (indirect-function fun) 'fun)))
+                     ;; Don't use find-function-noselect because it follows
+                     ;; aliases (which fails for built-in functions).
+                     (let ((location
+                            (find-function-search-for-symbol fun type file)))
+                       (pop-to-buffer (car location))
+                       (run-hooks 'find-function-after-hook)
+                       (if (cdr location)
+                           (goto-char (cdr location))
+                         (message "Unable to find location in file")))))
+  'help-echo (purecopy "mouse-2, RET: find function's definition"))
+
+;; Functions
+
+(defun info-compile-emacs-info-dir-content ()
+  "Build a list of file names from Emacs' info directories.
+This function fills `info-emacs-info-dir-content' with files from
+`Info-directory-list'."
+  (setq info-emacs-info-dir-content
+        (mapcar 'file-name-nondirectory ;'file-name-sans-extension
+                (directory-files
+                 (car
+                  ;; search for the main Emacs' info/ directory, when this
+                  ;; function is called Info-directory-list is already
+                  ;; initialised
+                  (cl-member "[^.]emacs" Info-directory-list :test
+                             'string-match-p))
+                 ;; don't list "." and ".."
+                 t  "[^.]$"))))
+
+(defun info-button-action (button)
+  "Call BUTTON's help function."
+  (info-do-xref nil
+                (button-get button 'info-function)
+                (button-get button 'info-args)))
+
+(defun info-do-xref (_pos function args)
+  "Call the help cross-reference function FUNCTION with args ARGS.
+Things are set up properly so that the resulting `help-buffer' has
+a proper [back] button."
+  ;; There is a reference at point.  Follow it.
+  (let ((help-xref-following nil))
+    (apply
+     function (if (eq function 'info)
+                  (append args (list (generate-new-buffer-name "*info*")))args))))
+
+(defun info-button (match-number type &rest args)
+  "Make a hyperlink for cross-reference text previously matched.
+MATCH-NUMBER is the subexpression of interest in the last matched
+regexp.  TYPE is the type of button to use.  Any remaining arguments are
+passed to the button's info-function when it is invoked.
+See `info-make-xrefs' Don't forget ARGS."
+  ;; Don't munge properties we've added, especially in some instances.
+  (unless (button-at (match-beginning match-number))
+    ;; (message "Creating button: %s." args)
+    (make-text-button (match-beginning match-number)
+                      (match-end match-number)
+                      'type type 'info-args args)))
+
+(defvar info-symbol-context
+  '(( variable . "variable\\|option")
+    ( function . "function\\|command\\|call")
+    ( face . "face")
+    ( ignore . "symbol\\|program\\|property")
+    ;; ignore symbols following this context type
+    ( definition . "source \\(?:code \\)?\\(?:of\\|for\\)"))
+  ;; function definitions in files
+  "This list helps to distinguish symbol types.
+Words in info documentation preceding a (quoted) symbol are used
+to distinguish variables, functions, faces and symbols.  The
+context information can also be used to ignore symbols because
+there is no help documentation for them.  The strings of the the
+list are becoming part of `info-symbol-regexp'.")
+
+(defvar info-symbol-regexp
+  ;; use purecopy?
+  (concat
+   "\\("                                ; Context start
+   "\\<\\("                             ; Contex type definition
+   (string-remove-suffix
+    "\\|"
+    (mapconcat
+     (lambda (x) (concat "\\(" (cdr x) "\\)\\|"))
+     info-symbol-context ""))
+   "\\)"          ; Context type definition end
+   "[ \t\n]+"     ; Separators to quoted symbols
+   "\\)?"         ; End of context
+   ;; quoted symbol
+   "['`‘]"	  ; opening quotes
+   ;; Note: Symbol starting with word-syntax character:
+   "\\(\\sw\\(\\sw\\|\\s_\\)+\\|`\\)" ; The symbol itself
+   "['’]"                             ; End quotes
+   )
+  "The regular expression for matching symbols to their help documentation.
+It is comprised of the symbol's context and the (quoted) symbol
+name.  The various groups of context regular expressions are
+matched in `info-make-xrefs' to distinct info buttons.")
+
+(defun info-check-type( type)
+  "Check if TYPE corresponds to the current search result.
+The function is used in `info-make-xrefs'."
+  (let* ((isc info-symbol-context)
+	 (n 3)                           ;embedded within 2 groups
+         (l (+ 3 (length isc))))
+    (while (and (not (eq type (caar isc) ) ) (< n l) )
+      (setq n (1+ n))
+      (setq isc (cdr isc)))
+    (match-string n)))
+
+\f
+;;;###autoload
+(defun info-make-xrefs (&optional buffer)
+  "Parse and hyperlink documentation cross-references in the given BUFFER.
+Find cross-reference information in a buffer and activate such
+cross references for selection with `help-follow'.  The current
+buffer is processed if the BUFFER argument is omitted.
+
+ Cross-references have the canonical (quoted) form `symbol-name'
+and the type of reference may be disambiguated by the preceding
+word(s) as compiled in `info-symbol-regexp'.  For example: Symbol
+names are receiving distinct variable buttons when preceeded by
+the words \"variable\" or \"option\".
+
+Variables are also detected when their names follow below form:
+
+ -- User Option: variable-name
+ -- Variable: ...
+
+Function names are also detected when prefixed by `M-x`, for
+example `M-x function-name` or are quoted and prefixed like `M-x
+function-name`.
+
+Function names are detected, as well, when appearing behind the
+following forms, which occur - for example - in the Elisp manual:
+
+ -- Special Form: function-name
+ -- Command: ...
+ -- Function: ...
+ -- Macro: ...
+
+The linking is similar to mechanisms from lisp/help.el."
+  (interactive "b")
+  (when (info-check-docu-p)
+    (with-current-buffer (or buffer (current-buffer))
+      (save-excursion
+        (goto-char (point-min))
+        (with-silent-modifications      ;hint from Stefan
+          (let ((case-fold-search t)
+                (inhibit-read-only t))
+            (with-syntax-table emacs-lisp-mode-syntax-table
+              ;; Quoted symbols
+              (save-excursion
+                (while (re-search-forward info-symbol-regexp nil t)
+                  (let* ((sym-group (+ 3 (length info-symbol-context)))
+                         (data (match-string sym-group))
+                         (sym (intern-soft data)))
+                    (if sym
+                        (cond
+                         ((info-check-type 'variable)
+                          (and (or (boundp sym)
+                                   (get sym 'variable-documentation))
+                               (info-button sym-group 'info-variable sym)))
+                         ((info-check-type 'function)
+                          (and (fboundp sym)
+                               (info-button sym-group 'info-function sym)))
+                         ((info-check-type 'face)
+                          (and (facep sym)
+                               (info-button sym-group 'info-face sym)))
+                         ((info-check-type 'ignore))
+                         ((info-check-type 'definition)
+                          (info-button sym-group 'info-function-def sym))
+                         ;; symbols
+                         ((cl-some (lambda (x) (funcall (nth 1 x) sym))
+                                   describe-symbol-backends)
+                          (info-button sym-group 'info-symbol sym)))))))
+              ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+              ;; (info "(elisp) Eval")
+              ;; Elisp manual      -- Special Form:
+              ;;                   -- Command:
+              ;;                   -- Function: function-name function
+              ;;                   -- Macro:
+              (save-excursion
+                (while (re-search-forward
+                        "-- \\(Special Form:\\|Command:\\|Function:\\|Macro:\\) "
+                        nil t)
+                  (looking-at "\\(\\sw\\|\\s_\\)+")
+                  (let ((sym (intern-soft (match-string 0))))
+                    (if (fboundp sym)
+                        (info-button 0 'info-function sym)))))
+              ;;              -- User Option:
+              ;;              -- Variable: variable-name
+              (save-excursion
+                (while (re-search-forward
+                        "-- \\(User Option:\\|Variable:\\) "
+                        nil t)
+                  (looking-at "\\(\\sw\\|\\s_\\)+")
+                  (let ((sym (intern-soft (match-string 0))))
+                    (if (boundp sym)
+                        (info-button 0 'info-variable sym)))))
+              ;; M-x prefixed functions
+              (save-excursion
+                (while (re-search-forward
+                        ;; Assume command name is only word and symbol
+                        ;; characters to get things like `use M-x foo->bar'.
+                        ;; Command required to end with word constituent
+                        ;; to avoid `.' at end of a sentence.
+                        ;; "\\<M-x\\s-+\\(\\sw\\(\\sw\\|\\s_\\)*\\sw\\)" nil t)
+                        ;; include M-x and quotes
+                        "['`‘]?M-x\\s-*\n?\\(\\sw\\(\\sw\\|\\s_\\)*\\sw\\)['’]?" nil t)
+                  (let ((sym (intern-soft (match-string 1))))
+                    (if (fboundp sym)
+                        (info-button 1 'info-function sym))))))))))))
+
 (provide 'info)
 
 ;;; info.el ends here
-- 
2.34.1


[-- Attachment #4: Type: text/plain, Size: 56 bytes --]


-- 
Best wishes
H. Dieter Wilhelm
Zwingenberg, Germany

^ permalink raw reply related	[flat|nested] 58+ messages in thread

* bug#60587: Patch for adding links to symbols' help documentation
  2023-01-25 21:29             ` H. Dieter Wilhelm
@ 2023-01-25 22:24               ` Drew Adams
  2023-01-26 10:29                 ` Ihor Radchenko
  2023-01-27 21:35                 ` H. Dieter Wilhelm
  2023-01-26 10:37               ` Eli Zaretskii
  1 sibling, 2 replies; 58+ messages in thread
From: Drew Adams @ 2023-01-25 22:24 UTC (permalink / raw)
  To: H. Dieter Wilhelm, Eli Zaretskii
  Cc: 60587@debbugs.gnu.org, monnier@iro.umontreal.ca

Some quick minor feedback -

1.
+  :type '(choice (const :tag "Create links" t)
+                 (const :tag "Do not link" nil))

is better as just :type 'boolean, and say in the
doc which Boolean value means which behavior.

2.
+;; Toggle on or off the linking to help documents
+(when info-make-xref-flag
+  (add-hook 'Info-selection-hook 'info-make-xrefs))

Instead of putting it on the hook when loading the
code, add/remove it in a :set function.  E.g.
(untested):

:set (lambda (sym defs)
       (custom-set-default sym defs)
       (let ((fun  (if info-make-xref-flag
                       #'add-hook
                     #'remove-hook)))
         (funcall fun 'Info-selection-hook
                      'info-make-xrefs)))

3. Maybe add a toggle command for the option, so
users can switch the behavior anytime, on the fly.

4. Or instead of having an option, maybe just have
a minor mode.

5. Face `info-color' should be named something like
`info-symbol-help-link'.

6. "clicking @kbd{mouse-2} or @kbd{mouse-1} on it"
can't be right, I think.  At least that doesn't
express what `mouse-1-follows-link' does/means.

7. Again, I think it's unhelpful to call these
links "buttons".  Especially since Info docs call
Info links "links".  That these links show their
destination in another window isn't a reason to
call them something different (and with no
definition of the additional term "button").






^ permalink raw reply	[flat|nested] 58+ messages in thread

* bug#60587: Patch for adding links to symbols' help documentation
  2023-01-25 22:24               ` Drew Adams
@ 2023-01-26 10:29                 ` Ihor Radchenko
  2023-01-26 15:06                   ` Drew Adams
  2023-01-27 21:35                 ` H. Dieter Wilhelm
  1 sibling, 1 reply; 58+ messages in thread
From: Ihor Radchenko @ 2023-01-26 10:29 UTC (permalink / raw)
  To: Drew Adams
  Cc: H. Dieter Wilhelm, Eli Zaretskii, 60587@debbugs.gnu.org,
	monnier@iro.umontreal.ca

Drew Adams <drew.adams@oracle.com> writes:

> Instead of putting it on the hook when loading the
> code, add/remove it in a :set function.  E.g.
> (untested):
>
> :set (lambda (sym defs)
>        (custom-set-default sym defs)
>        (let ((fun  (if info-make-xref-flag
>                        #'add-hook
>                      #'remove-hook)))
>          (funcall fun 'Info-selection-hook
>                       'info-make-xrefs)))
>
> 3. Maybe add a toggle command for the option, so
> users can switch the behavior anytime, on the fly.

What about using `add-variable-watcher'?

-- 
Ihor Radchenko // yantar92,
Org mode contributor,
Learn more about Org mode at <https://orgmode.org/>.
Support Org development at <https://liberapay.com/org-mode>,
or support my work at <https://liberapay.com/yantar92>





^ permalink raw reply	[flat|nested] 58+ messages in thread

* bug#60587: Patch for adding links to symbols' help documentation
  2023-01-25 21:29             ` H. Dieter Wilhelm
  2023-01-25 22:24               ` Drew Adams
@ 2023-01-26 10:37               ` Eli Zaretskii
  2023-01-27  7:45                 ` Juri Linkov
                                   ` (2 more replies)
  1 sibling, 3 replies; 58+ messages in thread
From: Eli Zaretskii @ 2023-01-26 10:37 UTC (permalink / raw)
  To: H. Dieter Wilhelm, Juri Linkov; +Cc: 60587, monnier

> From: "H. Dieter Wilhelm" <dieter@duenenhof-wilhelm.de>
> Cc: monnier@iro.umontreal.ca,  60587@debbugs.gnu.org
> Date: Wed, 25 Jan 2023 22:29:31 +0100
> 
> > So I guess you will be submitting a new patch soon?
> 
> Below it is (based on a recent master commit).
> 
> > I think the first sentence should be rewritten as describing a
> > separate feature, not "the same as" something else.  Just say that
> > symbols are converted into buttons that lead to their doc strings.
> >
> > Also, the option which controls this should be mentioned and indexed.
> 
> Please have a look at a further documentation patch.

Thanks.

Juri, any comments?

> +  In Info buffers quoted symbol names are made into buttons which show
> +the symbols' help documentation when typing @key{RET} or clicking
> +@kbd{mouse-2} or @kbd{mouse-1} on it.  For example, the quoted name
> +@code{info-other-window} is made into a button which shows the
> +function's documentation string in another window, in the
> +@file{*Help*} buffer.  Such quoted symbols (variables, functions and
> +face names) are highlighted by a distinct face and can be reached, as
> +the Info manual references, with @key{TAB} and @kbd{S-Tab}.

This is fine, but please try to reword to not use the passive tense so
much.

> +;; The code below provides links of symbols (functions, variables, and
> +;; faces) within Emacs' Info viewer to their builtin help
> +;; documentation.  This linking is done when symbol names in texinfo
> +;; documentation (like the Emacs- and Elisp manual) are:
> +
> +;; 1. Quoted symbol names like `quoted-symbol' or:

You seem to have lost that ", or" in the rest of the items:

> +;; 2. Function names which are prefixed by M-x, for example M-x
> +;; function-name or are quoted and prefixed, like `M-x function-name'.
> +
> +;; 3. Function names appearing behind the following forms, which
> +;; occur, for example, in the Elisp manual:
> +
> +;;   -- Special Form: function-name
> +;;   -- Command: ...
> +;;   -- Function: ...
> +;;   -- Macro: ...
> +
> +;; 4. And variables names behind the following text:
> +
> +;;   -- User Option: variable-name
> +;;   -- Variable: ...

> +(defun info-check-docu-p ()
> +  "Check if the current info file is relevant to Emacs or Elisp.
> +That means `Info-current-file' is either found in Emacs' info/
> +directory or in `package-user-dir' and is not included in the
> +`info-none-emacs-or-elisp-documents' list."
> +  (unless info-emacs-info-dir-content
> +    (info-compile-emacs-info-dir-content))
> +  (let* ((ifile Info-current-file)
> +         (ifi (when ifile
> +                (file-name-sans-extension
> +                 (file-name-nondirectory ifile))))
> +         (pdir (when (boundp 'package-user-dir)
> +                 (expand-file-name
> +                  package-user-dir)))
> +         ;; Check if checking pdir is redundant because Package adds
> +         ;; info package folders to Info-directory-list anyway?
> +         (ifiles info-emacs-info-dir-content)
> +         (ndocu info-none-emacs-or-elisp-documents)
> +         (is-info (and ifile
> +                       (or (assoc-string (concat ifi ".info") ifiles)
> +                           ;; the top info "dir" file
> +                           (assoc-string (concat ifi ".info.gz") ifiles)
> +                           ;; info files might be archived!
> +                           (when pdir (string-match pdir ifile)))
> +                       (not (assoc-string ifi ndocu)))))

This should probably be extended to allow more extensions; see
Info-suffix-list.

> +(defface info-color
> +  '((t (:inherit font-lock-doc-face

Why not inherit from the 'link' face?

> +(defvar-keymap info-button-map
> +  :doc "Keymap used by buttons in Info buffers."
> +  "RET" #'push-button
> +  "<mouse-2>" #'push-button
> +  "<follow-link>" 'mouse-face
> +  ;; FIXME: You'd think that for keymaps coming from text-properties on the
> +  ;; mode-line or header-line, the `mode-line' or `header-line' prefix
> +  ;; shouldn't be necessary!
> +  "<mode-line> <mouse-2>" #'push-button
> +  "<header-line> <mouse-2>" #'push-button)

Is this FXIME important enough to leave in the final version?

> +(defun info-compile-emacs-info-dir-content ()
> +  "Build a list of file names from Emacs' info directories.
> +This function fills `info-emacs-info-dir-content' with files from
> +`Info-directory-list'."
> +  (setq info-emacs-info-dir-content
> +        (mapcar 'file-name-nondirectory ;'file-name-sans-extension

The comment should be removed, yes?

> +(defun info-button (match-number type &rest args)
> +  "Make a hyperlink for cross-reference text previously matched.
> +MATCH-NUMBER is the subexpression of interest in the last matched
> +regexp.  TYPE is the type of button to use.  Any remaining arguments are
> +passed to the button's info-function when it is invoked.
> +See `info-make-xrefs' Don't forget ARGS."
                       ^^^
A period is missing there.

> +  ;; Don't munge properties we've added, especially in some instances.
> +  (unless (button-at (match-beginning match-number))
> +    ;; (message "Creating button: %s." args)
> +    (make-text-button (match-beginning match-number)
> +                      (match-end match-number)
> +                      'type type 'info-args args)))

The "message" call in the comment should be removed.

> +
> +(defvar info-symbol-context
> +  '(( variable . "variable\\|option")
> +    ( function . "function\\|command\\|call")
> +    ( face . "face")
> +    ( ignore . "symbol\\|program\\|property")

Extra whitespace after an opening parenthesis.

> +    ;; ignore symbols following this context type
> +    ( definition . "source \\(?:code \\)?\\(?:of\\|for\\)"))
> +  ;; function definitions in files

These comments should be moved to _before_ the lines on which they
comment.

> +(defun info-make-xrefs (&optional buffer)
> +  "Parse and hyperlink documentation cross-references in the given BUFFER.
> +Find cross-reference information in a buffer and activate such
> +cross references for selection with `help-follow'.  The current
> +buffer is processed if the BUFFER argument is omitted.

Our style for the last sentence is

  BUFFER defaults to the current buffer if omitted or nil.

I'd also move it to be the second sentence of the doc string.

> +Function names are also detected when prefixed by `M-x`, for
> +example `M-x function-name` or are quoted and prefixed like `M-x
> +function-name`.

Please quote in doc strings `like this', not `like this`.  The latter
is not supported by the Emacs Help features.





^ permalink raw reply	[flat|nested] 58+ messages in thread

* bug#60587: Patch for adding links to symbols' help documentation
  2023-01-26 10:29                 ` Ihor Radchenko
@ 2023-01-26 15:06                   ` Drew Adams
  2023-01-26 15:12                     ` Ihor Radchenko
  0 siblings, 1 reply; 58+ messages in thread
From: Drew Adams @ 2023-01-26 15:06 UTC (permalink / raw)
  To: Ihor Radchenko
  Cc: H. Dieter Wilhelm, Eli Zaretskii, 60587@debbugs.gnu.org,
	monnier@iro.umontreal.ca

> > 2. Instead of putting it on the hook when loading
> > the code, add/remove it in a :set function.  E.g.
> > (untested):...
> >
> > 3. Maybe add a toggle command for the option, so
> > users can switch the behavior anytime, on the fly.
> 
> What about using `add-variable-watcher'?

Did you mean for #2: when/where to add the function
to the hook?  Or did you mean use a watcher instead
of #3, a toggle command?

Assuming you meant #2:

Also possible.  Seems a bit overkill to me, though.

This is what :set is for, for options.  A variable
watcher can do anything, not just for an option,
and not just when the var is set.





^ permalink raw reply	[flat|nested] 58+ messages in thread

* bug#60587: Patch for adding links to symbols' help documentation
  2023-01-26 15:06                   ` Drew Adams
@ 2023-01-26 15:12                     ` Ihor Radchenko
  2023-01-26 15:23                       ` Drew Adams
  0 siblings, 1 reply; 58+ messages in thread
From: Ihor Radchenko @ 2023-01-26 15:12 UTC (permalink / raw)
  To: Drew Adams
  Cc: H. Dieter Wilhelm, Eli Zaretskii, 60587@debbugs.gnu.org,
	monnier@iro.umontreal.ca

Drew Adams <drew.adams@oracle.com> writes:

>> > 2. Instead of putting it on the hook when loading
>> > the code, add/remove it in a :set function.  E.g.
>> > (untested):...
>> >
>> > 3. Maybe add a toggle command for the option, so
>> > users can switch the behavior anytime, on the fly.
>> 
>> What about using `add-variable-watcher'?
>
> Did you mean for #2: when/where to add the function
> to the hook?  Or did you mean use a watcher instead
> of #3, a toggle command?

Both. Rather than searching for a dedicated "toggle" command, setting
the variable with then trigger the hook addition/removal.

-- 
Ihor Radchenko // yantar92,
Org mode contributor,
Learn more about Org mode at <https://orgmode.org/>.
Support Org development at <https://liberapay.com/org-mode>,
or support my work at <https://liberapay.com/yantar92>





^ permalink raw reply	[flat|nested] 58+ messages in thread

* bug#60587: Patch for adding links to symbols' help documentation
  2023-01-26 15:12                     ` Ihor Radchenko
@ 2023-01-26 15:23                       ` Drew Adams
  0 siblings, 0 replies; 58+ messages in thread
From: Drew Adams @ 2023-01-26 15:23 UTC (permalink / raw)
  To: Ihor Radchenko
  Cc: H. Dieter Wilhelm, Eli Zaretskii, 60587@debbugs.gnu.org,
	monnier@iro.umontreal.ca

> >> > 2. Instead of putting it on the hook when loading
> >> > the code, add/remove it in a :set function.  E.g.
> >> > (untested):...
> >> >
> >> > 3. Maybe add a toggle command for the option, so
> >> > users can switch the behavior anytime, on the fly.
> >>
> >> What about using `add-variable-watcher'?
> >
> > Did you mean for #2: when/where to add the function
> > to the hook?  Or did you mean use a watcher instead
> > of #3, a toggle command?
> 
> Both. Rather than searching for a dedicated "toggle" command, setting
> the variable with then trigger the hook addition/removal.

Doesn't matter what I think here, and I may
be missing your point.  But, in case it helps:

1. :set takes care of what you say.  And it's
   specifically for (1) only setting and (2)
   only user options.

2. I don't see how a watcher provides users
   with a command, to interactively toggle
   the value.

3. Cf. the suggestion to use a minor mode.





^ permalink raw reply	[flat|nested] 58+ messages in thread

* bug#60587: Patch for adding links to symbols' help documentation
  2023-01-26 10:37               ` Eli Zaretskii
@ 2023-01-27  7:45                 ` Juri Linkov
  2023-01-27  8:11                   ` Eli Zaretskii
  2023-01-27 22:21                 ` H. Dieter Wilhelm
  2023-02-01 21:26                 ` H. Dieter Wilhelm
  2 siblings, 1 reply; 58+ messages in thread
From: Juri Linkov @ 2023-01-27  7:45 UTC (permalink / raw)
  To: Eli Zaretskii; +Cc: H. Dieter Wilhelm, 60587, monnier

>> > So I guess you will be submitting a new patch soon?
>>
>> Below it is (based on a recent master commit).
>>
>> > I think the first sentence should be rewritten as describing a
>> > separate feature, not "the same as" something else.  Just say that
>> > symbols are converted into buttons that lead to their doc strings.
>> >
>> > Also, the option which controls this should be mentioned and indexed.
>>
>> Please have a look at a further documentation patch.
>
> Thanks.
>
> Juri, any comments?

I think this is a nice feature, but it should be implemented
in a separate file.  The file info.el contains the features
that are used in all Info manuals.  OTOH, the proposed feature
can be used only for a small part of all manuals, namely
only for manuals that describe Emacs core and packages.





^ permalink raw reply	[flat|nested] 58+ messages in thread

* bug#60587: Patch for adding links to symbols' help documentation
  2023-01-27  7:45                 ` Juri Linkov
@ 2023-01-27  8:11                   ` Eli Zaretskii
  0 siblings, 0 replies; 58+ messages in thread
From: Eli Zaretskii @ 2023-01-27  8:11 UTC (permalink / raw)
  To: Juri Linkov; +Cc: dieter, 60587, monnier

> From: Juri Linkov <juri@linkov.net>
> Cc: "H. Dieter Wilhelm" <dieter@duenenhof-wilhelm.de>,
>   monnier@iro.umontreal.ca,  60587@debbugs.gnu.org
> Date: Fri, 27 Jan 2023 09:45:17 +0200
> 
> >> > So I guess you will be submitting a new patch soon?
> >>
> >> Below it is (based on a recent master commit).
> >>
> >> > I think the first sentence should be rewritten as describing a
> >> > separate feature, not "the same as" something else.  Just say that
> >> > symbols are converted into buttons that lead to their doc strings.
> >> >
> >> > Also, the option which controls this should be mentioned and indexed.
> >>
> >> Please have a look at a further documentation patch.
> >
> > Thanks.
> >
> > Juri, any comments?
> 
> I think this is a nice feature, but it should be implemented
> in a separate file.  The file info.el contains the features
> that are used in all Info manuals.  OTOH, the proposed feature
> can be used only for a small part of all manuals, namely
> only for manuals that describe Emacs core and packages.

It was originally on a separate file, but I thought, and still think,
that it should be in info.el.  I don't see any significance in the
fact that this will be used for manuals that come with Emacs, as those
are quite numerous.  E.g., on my system, Emacs manuals are about 1/4th
of all the installed manuals, and I have a lot of Info manuals other
than Emacs and no Info manuals that come with ELPA packages.





^ permalink raw reply	[flat|nested] 58+ messages in thread

* bug#60587: Patch for adding links to symbols' help documentation
  2023-01-25 22:24               ` Drew Adams
  2023-01-26 10:29                 ` Ihor Radchenko
@ 2023-01-27 21:35                 ` H. Dieter Wilhelm
  2023-01-27 22:12                   ` Stefan Monnier via Bug reports for GNU Emacs, the Swiss army knife of text editors
  2023-01-27 23:13                   ` Drew Adams
  1 sibling, 2 replies; 58+ messages in thread
From: H. Dieter Wilhelm @ 2023-01-27 21:35 UTC (permalink / raw)
  To: Drew Adams; +Cc: Eli Zaretskii, 60587@debbugs.gnu.org, monnier@iro.umontreal.ca

Hi Drew

Thank you for your ideas!

Drew Adams <drew.adams@oracle.com> writes:

> 1.
> +  :type '(choice (const :tag "Create links" t)
> +                 (const :tag "Do not link" nil))
>
> is better as just :type 'boolean, and say in the
> doc which Boolean value means which behavior.

The doc string says now:

  "True (`t') means Emacs creates symbol link buttons in Info.
Setting this variable to `nil' inhibits the creation of buttons
on quoted symbols to their help strings.  Please see the function
`info-make-xrefs' for further details."

> 2.
> +;; Toggle on or off the linking to help documents
> +(when info-make-xref-flag
> +  (add-hook 'Info-selection-hook 'info-make-xrefs))

Yes, the above is rather crude.

> Instead of putting it on the hook when loading the
> code, add/remove it in a :set function.  E.g.
> (untested):
>
> :set (lambda (sym defs)
>        (custom-set-default sym defs)
>        (let ((fun  (if info-make-xref-flag
>                        #'add-hook
>                      #'remove-hook)))
>          (funcall fun 'Info-selection-hook
>                       'info-make-xrefs)))

It works nicely and I put this setter in `info-make-xref-flag'. :-)

> 3. Maybe add a toggle command for the option, so users can switch the
> behavior anytime, on the fly.

Like this?

;; TODO: add this toggle in info documentation and NEWS
;; TODO: remove and create buttons in current info buffer
(defun info-toggle-make-xrefs ()
  "Toggle creating Info buttons."
  (interactive)
  (if (memq 'info-make-xrefs Info-selection-hook)
      (remove-hook 'Info-selection-hook 'info-make-xrefs)
    (add-hook 'Info-selection-hook 'info-make-xrefs)
    (message "Create Info link buttons to symbol names.")))
 

> 4. Or instead of having an option, maybe just have
> a minor mode.

That's also a nice idea.  (Maybe for later.)

> 5. Face `info-color' should be named something like
> `info-symbol-help-link'.

You're right, `info-color' is too minimalist and not describing what the
object represents.

(I dropped it completely because I realised an additional face is
redundant since Info distinguishes (slightly) quoted symbols from the
text, anyway.)

> 6. "clicking @kbd{mouse-2} or @kbd{mouse-1} on it"
> can't be right, I think.  At least that doesn't
> express what `mouse-1-follows-link' does/means.

Do you mean that I should just say mouse-2, because
`mouse-1-click-follows-link' regulates it anyhow?  (E.g. I realised that
Emacs changes my documentation string for the tooltips

  'help-echo (purecopy "mouse-2, RET: describe this variable"))

from mouse-2 to mouse-1!)

> 7. Again, I think it's unhelpful to call these
> links "buttons".  Especially since Info docs call
> Info links "links".  That these links show their
> destination in another window isn't a reason to
> call them something different (and with no
> definition of the additional term "button").

To make the confusion complete: Info documentations calls (Info) links
also cross-references. ;-)

(info "(info)Help-Xref")

Thanks again

       Dieter

-- 
Best wishes
H. Dieter Wilhelm
Zwingenberg, Germany





^ permalink raw reply	[flat|nested] 58+ messages in thread

* bug#60587: Patch for adding links to symbols' help documentation
  2023-01-27 21:35                 ` H. Dieter Wilhelm
@ 2023-01-27 22:12                   ` Stefan Monnier via Bug reports for GNU Emacs, the Swiss army knife of text editors
  2023-01-27 23:09                     ` Drew Adams
  2023-01-27 23:13                   ` Drew Adams
  1 sibling, 1 reply; 58+ messages in thread
From: Stefan Monnier via Bug reports for GNU Emacs, the Swiss army knife of text editors @ 2023-01-27 22:12 UTC (permalink / raw)
  To: H. Dieter Wilhelm; +Cc: Eli Zaretskii, 60587@debbugs.gnu.org, Drew Adams

>> 3. Maybe add a toggle command for the option, so users can switch the
>> behavior anytime, on the fly.
>
> Like this?
>
> ;; TODO: add this toggle in info documentation and NEWS
> ;; TODO: remove and create buttons in current info buffer
> (defun info-toggle-make-xrefs ()
>   "Toggle creating Info buttons."
>   (interactive)
>   (if (memq 'info-make-xrefs Info-selection-hook)
>       (remove-hook 'Info-selection-hook 'info-make-xrefs)
>     (add-hook 'Info-selection-hook 'info-make-xrefs)
>     (message "Create Info link buttons to symbol names.")))

Make it a minor mode, then.  It's no more coding and it offers more
functionality and a more regular/familiar behavior.


        Stefan






^ permalink raw reply	[flat|nested] 58+ messages in thread

* bug#60587: Patch for adding links to symbols' help documentation
  2023-01-26 10:37               ` Eli Zaretskii
  2023-01-27  7:45                 ` Juri Linkov
@ 2023-01-27 22:21                 ` H. Dieter Wilhelm
  2023-01-28  7:51                   ` Eli Zaretskii
  2023-02-01 21:26                 ` H. Dieter Wilhelm
  2 siblings, 1 reply; 58+ messages in thread
From: H. Dieter Wilhelm @ 2023-01-27 22:21 UTC (permalink / raw)
  To: Eli Zaretskii; +Cc: 60587, monnier, Juri Linkov

Thank you for your help.

Eli Zaretskii <eliz@gnu.org> writes:

>> +  In Info buffers quoted symbol names are made into buttons which show
>> +the symbols' help documentation when typing @key{RET} or clicking
>> +@kbd{mouse-2} or @kbd{mouse-1} on it.  For example, the quoted name
>> +@code{info-other-window} is made into a button which shows the
>> +function's documentation string in another window, in the
>> +@file{*Help*} buffer.  Such quoted symbols (variables, functions and
>> +face names) are highlighted by a distinct face and can be reached, as
>> +the Info manual references, with @key{TAB} and @kbd{S-Tab}.
>
> This is fine, but please try to reword to not use the passive tense so
> much.

What do you think about the following formulation, is it already a
better "mix"?

  Info makes quoted symbol names into buttons which show the symbols'
help documentation when typing @key{RET} or clicking @kbd{mouse-2} or
@kbd{mouse-1} on it.  For example, the quoted name
@code{info-other-window} is made into a button which shows the
function's documentation string in another window, in the
@file{*Help*} buffer.  Info highlights such quoted symbols (variables,
functions and face names) by a distinct face and these can be reached,
as regular Info manual references, with @key{TAB} and @kbd{S-Tab}.

Drew reminded me that it should be better to write solely @kbd{mouse-2}
and / or possibly explaining `mouse-1-click-follows-link'.  I'm curious
about your opinion.

>> +;; The code below provides links of symbols (functions, variables, and
>> +;; faces) within Emacs' Info viewer to their builtin help
>> +;; documentation.  This linking is done when symbol names in texinfo
>> +;; documentation (like the Emacs- and Elisp manual) are:
>> +
>> +;; 1. Quoted symbol names like `quoted-symbol' or:
>
> You seem to have lost that ", or" in the rest of the items:

I wanted to express:
;; 1. Quoted symbol names like `quoted-symbol' or 2. (below).

;; 2. Function names which are prefixed by M-x, for example M-x

But you're right, since we are already in a numbered list, I dropped the
redundant phrase:

;; 1. Quoted symbol names like `quoted-symbol'.

;; 2. Function names which are prefixed by M-x, for example M-x

>> +                       (or (assoc-string (concat ifi ".info") ifiles)
>> +                           ;; the top info "dir" file
>> +                           (assoc-string (concat ifi ".info.gz") ifiles)
>> +                           ;; info files might be archived!
>> +                           (when pdir (string-match pdir ifile)))
>> +                       (not (assoc-string ifi ndocu)))))
>
> This should probably be extended to allow more extensions; see
> Info-suffix-list.

Thanks for hinting at Info-suffix-list. I'll try to accommodate the
other suffices in the code and will send another iteration of info.el
patches.

>> +(defface info-color
>> +  '((t (:inherit font-lock-doc-face
>
> Why not inherit from the 'link' face?

I wanted a different face compared to the regular Info links.  Because
they are acting differently!

But yesterday I realised that Info distinguishes (slightly) already
quoted symbols from the regular text.  I dropped now the info-color face
because the user can sufficiently distinguish between text, buttons and
Info links.

>> +(defvar-keymap info-button-map
>> +  :doc "Keymap used by buttons in Info buffers."
>> +  "RET" #'push-button
>> +  "<mouse-2>" #'push-button
>> +  "<follow-link>" 'mouse-face
>> +  ;; FIXME: You'd think that for keymaps coming from text-properties on the
>> +  ;; mode-line or header-line, the `mode-line' or `header-line' prefix
>> +  ;; shouldn't be necessary!
>> +  "<mode-line> <mouse-2>" #'push-button
>> +  "<header-line> <mouse-2>" #'push-button)
>
> Is this FXIME important enough to leave in the final version?

I really don't know, just copied the complete keymap code from
button.el.  (The comment is gone now.)

>> +(defun info-compile-emacs-info-dir-content ()
>> +  "Build a list of file names from Emacs' info directories.
>> +This function fills `info-emacs-info-dir-content' with files from
>> +`Info-directory-list'."
>> +  (setq info-emacs-info-dir-content
>> +        (mapcar 'file-name-nondirectory ;'file-name-sans-extension
>
> The comment should be removed, yes?

Yes, it's gone.

>> +(defun info-button (match-number type &rest args)
>> +  "Make a hyperlink for cross-reference text previously matched.
>> +MATCH-NUMBER is the subexpression of interest in the last matched
>> +regexp.  TYPE is the type of button to use.  Any remaining arguments are
>> +passed to the button's info-function when it is invoked.
>> +See `info-make-xrefs' Don't forget ARGS."
>                        ^^^
> A period is missing there.

Yes, a period and a whitespace ;-)

>> +  ;; Don't munge properties we've added, especially in some instances.
>> +  (unless (button-at (match-beginning match-number))
>> +    ;; (message "Creating button: %s." args)
>> +    (make-text-button (match-beginning match-number)
>> +                      (match-end match-number)
>> +                      'type type 'info-args args)))
>
> The "message" call in the comment should be removed.

Yes, I removed it now.

>> +
>> +(defvar info-symbol-context
>> +  '(( variable . "variable\\|option")
>> +    ( function . "function\\|command\\|call")
>> +    ( face . "face")
>> +    ( ignore . "symbol\\|program\\|property")
>
> Extra whitespace after an opening parenthesis.

Indeed, marked the whitespace column and C-x r t

>> +    ;; ignore symbols following this context type
>> +    ( definition . "source \\(?:code \\)?\\(?:of\\|for\\)"))
>> +  ;; function definitions in files

(changed also (definition ..) )

> These comments should be moved to _before_ the lines on which they
> comment.

Makes sense to be consistent 😅, improved that part.

>> +(defun info-make-xrefs (&optional buffer)
>> +  "Parse and hyperlink documentation cross-references in the given BUFFER.
>> +Find cross-reference information in a buffer and activate such
>> +cross references for selection with `help-follow'.  The current
>> +buffer is processed if the BUFFER argument is omitted.
>
> Our style for the last sentence is
>
>   BUFFER defaults to the current buffer if omitted or nil.
>
> I'd also move it to be the second sentence of the doc string.

I see, changed it in that way.

>> +Function names are also detected when prefixed by `M-x`, for
>> +example `M-x function-name` or are quoted and prefixed like `M-x
>> +function-name`.
>
> Please quote in doc strings `like this', not `like this`.  The latter
> is not supported by the Emacs Help features.

I'm sorry, when writing that piece I had Emacs wrongly configured
duplicating every ``' and didn't discern the difference.  ("Back" back
quotes are gone now.)

-- 
Best wishes
H. Dieter Wilhelm
Zwingenberg, Germany





^ permalink raw reply	[flat|nested] 58+ messages in thread

* bug#60587: Patch for adding links to symbols' help documentation
  2023-01-27 22:12                   ` Stefan Monnier via Bug reports for GNU Emacs, the Swiss army knife of text editors
@ 2023-01-27 23:09                     ` Drew Adams
  0 siblings, 0 replies; 58+ messages in thread
From: Drew Adams @ 2023-01-27 23:09 UTC (permalink / raw)
  To: Stefan Monnier, H. Dieter Wilhelm; +Cc: Eli Zaretskii, 60587@debbugs.gnu.org

> Make it a minor mode, then.  It's no more coding and it offers
> more functionality and a more regular/familiar behavior.

Yes, that's what I meant.

But there's the wrinkle of whether users can just
Customize the variable value or need to turn on
the mode.  Vanilla Emacs doesn't like toggling of
user option values (I don't agree, FWIW), and in
Isearch, for example, has a user option and a
defvar for the same thing, with a toggle command
for the defvar value and the option just to set
the default of the defvar.

(I do agree that minor modes are generally a good
way to go, for toggles.)





^ permalink raw reply	[flat|nested] 58+ messages in thread

* bug#60587: Patch for adding links to symbols' help documentation
  2023-01-27 21:35                 ` H. Dieter Wilhelm
  2023-01-27 22:12                   ` Stefan Monnier via Bug reports for GNU Emacs, the Swiss army knife of text editors
@ 2023-01-27 23:13                   ` Drew Adams
  2023-01-28  8:11                     ` Eli Zaretskii
                                       ` (2 more replies)
  1 sibling, 3 replies; 58+ messages in thread
From: Drew Adams @ 2023-01-27 23:13 UTC (permalink / raw)
  To: H. Dieter Wilhelm
  Cc: Eli Zaretskii, 60587@debbugs.gnu.org, monnier@iro.umontreal.ca

> > 1.
> > +  :type '(choice (const :tag "Create links" t)
> > +                 (const :tag "Do not link" nil))
> >
> > is better as just :type 'boolean, and say in the
> > doc which Boolean value means which behavior.
> 
> The doc string says now:
> 
>   "True (`t') means Emacs creates symbol link buttons in Info.
> Setting this variable to `nil' inhibits the creation of buttons
> on quoted symbols to their help strings.  Please see the function
> `info-make-xrefs' for further details."

Is the defcustom now :type 'boolean?

> > 3. Maybe add a toggle command for the option, so users can switch the
> > behavior anytime, on the fly.
> 
> Like this?...
>
> > 4. Or instead of having an option, maybe just have
> > a minor mode.
> 
> That's also a nice idea.  (Maybe for later.)

See Stefan's reply...

> > 5. Face `info-color' should be named something like
> > `info-symbol-help-link'.
> 
> You're right, `info-color' is too minimalist and not describing what the
> object represents.
> 
> (I dropped it completely because I realised an additional face is
> redundant since Info distinguishes (slightly) quoted symbols from the
> text, anyway.)

I think it's _good_ to have a separate face for this.
That gives users the choice:

* Have the same appearance for both kinds of link.
* Have the two kinds of link (Info, *Help*) look
  different.

When you provide two faces, users can always customize
them to look the same, if they like.  Otherwise, they
don't have that possibility.

> > 6. "clicking @kbd{mouse-2} or @kbd{mouse-1} on it"
> > can't be right, I think.  At least that doesn't
> > express what `mouse-1-follows-link' does/means.
> 
> Do you mean that I should just say mouse-2, because
> `mouse-1-click-follows-link' regulates it anyhow?  (E.g. I realised that
> Emacs changes my documentation string for the tooltips
> 
>   'help-echo (purecopy "mouse-2, RET: describe this variable"))
> 
> from mouse-2 to mouse-1!)

Whatever Emacs expects.  Yes, I think that's what to
do - but someone may correct me.

> > 7. Again, I think it's unhelpful to call these
> > links "buttons".  Especially since Info docs call
> > Info links "links".  That these links show their
> > destination in another window isn't a reason to
> > call them something different (and with no
> > definition of the additional term "button").
> 
> To make the confusion complete: Info documentations
> calls (Info) links also cross-references. ;-)
> 
> (info "(info)Help-Xref")






^ permalink raw reply	[flat|nested] 58+ messages in thread

* bug#60587: Patch for adding links to symbols' help documentation
  2023-01-27 22:21                 ` H. Dieter Wilhelm
@ 2023-01-28  7:51                   ` Eli Zaretskii
  0 siblings, 0 replies; 58+ messages in thread
From: Eli Zaretskii @ 2023-01-28  7:51 UTC (permalink / raw)
  To: H. Dieter Wilhelm; +Cc: 60587, monnier, juri

> From: "H. Dieter Wilhelm" <dieter@duenenhof-wilhelm.de>
> Cc: Juri Linkov <juri@linkov.net>,  monnier@iro.umontreal.ca,
>   60587@debbugs.gnu.org
> Date: Fri, 27 Jan 2023 23:21:12 +0100
> 
> Eli Zaretskii <eliz@gnu.org> writes:
> 
> >> +  In Info buffers quoted symbol names are made into buttons which show
> >> +the symbols' help documentation when typing @key{RET} or clicking
> >> +@kbd{mouse-2} or @kbd{mouse-1} on it.  For example, the quoted name
> >> +@code{info-other-window} is made into a button which shows the
> >> +function's documentation string in another window, in the
> >> +@file{*Help*} buffer.  Such quoted symbols (variables, functions and
> >> +face names) are highlighted by a distinct face and can be reached, as
> >> +the Info manual references, with @key{TAB} and @kbd{S-Tab}.
> >
> > This is fine, but please try to reword to not use the passive tense so
> > much.
> 
> What do you think about the following formulation, is it already a
> better "mix"?
> 
>   Info makes quoted symbol names into buttons which show the symbols'
> help documentation when typing @key{RET} or clicking @kbd{mouse-2} or
> @kbd{mouse-1} on it.  For example, the quoted name
> @code{info-other-window} is made into a button which shows the
> function's documentation string in another window, in the
> @file{*Help*} buffer.  Info highlights such quoted symbols (variables,
> functions and face names) by a distinct face and these can be reached,
> as regular Info manual references, with @key{TAB} and @kbd{S-Tab}.

Yes, much better, thanks.

> Drew reminded me that it should be better to write solely @kbd{mouse-2}
> and / or possibly explaining `mouse-1-click-follows-link'.  I'm curious
> about your opinion.

I'd just say "click the mouse (@pxref{Mouse References})", since the
cross-referenced node already explains all of these subtleties, and
does it better.





^ permalink raw reply	[flat|nested] 58+ messages in thread

* bug#60587: Patch for adding links to symbols' help documentation
  2023-01-27 23:13                   ` Drew Adams
@ 2023-01-28  8:11                     ` Eli Zaretskii
  2023-01-28 17:30                       ` Drew Adams
  2023-02-01 22:09                     ` H. Dieter Wilhelm
  2023-02-05  0:48                     ` H. Dieter Wilhelm
  2 siblings, 1 reply; 58+ messages in thread
From: Eli Zaretskii @ 2023-01-28  8:11 UTC (permalink / raw)
  To: Drew Adams; +Cc: dieter, 60587, monnier

> From: Drew Adams <drew.adams@oracle.com>
> CC: Eli Zaretskii <eliz@gnu.org>,
>         "60587@debbugs.gnu.org"
> 	<60587@debbugs.gnu.org>,
>         "monnier@iro.umontreal.ca"
> 	<monnier@iro.umontreal.ca>
> Date: Fri, 27 Jan 2023 23:13:36 +0000
> 
> > > 5. Face `info-color' should be named something like
> > > `info-symbol-help-link'.
> > 
> > You're right, `info-color' is too minimalist and not describing what the
> > object represents.
> > 
> > (I dropped it completely because I realised an additional face is
> > redundant since Info distinguishes (slightly) quoted symbols from the
> > text, anyway.)
> 
> I think it's _good_ to have a separate face for this.

I disagree that another face is a Good Thing.  We have too many of
them already.

> That gives users the choice:
> 
> * Have the same appearance for both kinds of link.
> * Have the two kinds of link (Info, *Help*) look
>   different.
> 
> When you provide two faces, users can always customize
> them to look the same, if they like.  Otherwise, they
> don't have that possibility.

The downside of having a separate face is the need to know about it
and customize it separately.  So an additional face is not just an
advantage, it is also a disadvantage.  Thus, we should introduce new
faces only if they really are for a different purpose.  This one
isn't.





^ permalink raw reply	[flat|nested] 58+ messages in thread

* bug#60587: Patch for adding links to symbols' help documentation
  2023-01-28  8:11                     ` Eli Zaretskii
@ 2023-01-28 17:30                       ` Drew Adams
  0 siblings, 0 replies; 58+ messages in thread
From: Drew Adams @ 2023-01-28 17:30 UTC (permalink / raw)
  To: Eli Zaretskii
  Cc: dieter@duenenhof-wilhelm.de, 60587@debbugs.gnu.org,
	monnier@iro.umontreal.ca

[-- Attachment #1: Type: text/plain, Size: 4446 bytes --]

> > I think it's _good_ to have a separate face
> > for this.
> 
> I disagree that another face is a Good Thing.
> We have too many of them already.

I respectfully disagree.  I'll give my reasons
here, then call it quits.

Nothing prevents the new face from, by default,
inheriting its appearance from the other one.
(Though I'd much prefer that it not do that by
default.)

And nothing prevents its doc from pointing out
that that's the case.  So customizing the Info
link face gives the new Info *Help* link face
the same appearance (but not vice versa).

By inheriting, there is, in effect, a general
category: link in Info, and you can either have
all links in Info look the same or have the
two kinds look different.

> > That gives users the choice:
> >
> > * Have the same appearance for both kinds of link.
> > * Have the two kinds of link (Info, *Help*) look
> >   different.
> >
> > When you provide two faces, users can always customize
> > them to look the same, if they like.  Otherwise, they
> > don't have that possibility.
> 
> The downside of having a separate face is the need 
> to know about it and customize it separately.

"_Need_ to know about it"?  Why/when does anyone
need to know about it, any more than they need
to know about the Info link face?

Users can check which face is used somewhere,
and show both kinds of links with either
`list-faces-display' or `M-x customize-face'.

(BTW, shouldn't the Info faces for links be
included in group `info-xref-group'?  You
should be able to do `M-x customize-group
info-xref-group' and see `info-xref',
`info-xref-visited' and `info-header-xref'.)

> we should introduce new faces only if they
> really are for a different purpose.  This one
> isn't.

I think it is.  It's not for Info navigating.
It's not for following Info cross-references.
Its purpose is something different.

More importantly than what I think perhaps, is
that if you give users the choice, so they can
see a difference, and if some make the choice
to see it, they will have demonstrated that -
for them - the two do have different purposes.

This isn't really different from the choice we
made to have _three_ faces for following Info
xrefs: `info-xref', `info-xref-visited', and
`info-header-xref'.  Someone chose to have 3,
not 1, face for this.

I don't expect to convince you, and you've
maybe already decided about it.  But I'd like
to state my position and reasons about this.

The question about "too many faces" comes up
periodically.  Just as in taxonomy discussions,
there are those who are more "clumpers" and
those who are more "splitters".  When it comes
to faces, I tend to be more of a splitter.
(When it comes to letting users customize their
editor, Emacs itself is very much a splitter!)
___

Finally, here's an example of another Info
link face, which I added in my code.  It links
glossary words to their definitions in the
Glossary.  Unlike the new *Help* links, this
one is, like the *xref* faces, for navigating
in Info.

And like the new *Help* links, users are able
to hide/show its links on the fly.  Equally
important, only the _first_ occurrence in a
node of a given word is linked.  That too
would be useful for the new *Help* links, as
opposed to linking every occurrence of the
same symbol name (too noisy).

More generally, users can choose how and when
to show glossary links.

In addition to linking them, glossary words
in the text can show their definitions on
mouseover.

(Going to the Glossary lets you follow links
within the Glossary.  But there aren't many
of those, and a user might prefer to just
see definitions on mouseover.)

Choices (option `Info-link-glossary-words'):

1. Never (off).  Not even an invisible link.
2. Only until a link for that word has been
   visited.  But show a tooltip with the
   word's definition on mouseover.
3. Only until visited (no mouseover tooltip).
4. Always.  And show mouseover tooltip.
5. Always.  No mouseover tooltip.
6. Never - an invisible link, but show
   mouseover tooltip.
7. Never - invisible link, and no mouseover
   tooltip.

The default is #2.  Attached are screenshots
showing #2/#3, #5, and #6.

A toggle command toggles the option between
#1 (a nil value) and the last used of the
others (non-nil values).  A cycle command
cycles the option among the possible values.

[-- Attachment #2: throw-emacs-info-gloss-links-face+def.png --]
[-- Type: image/png, Size: 77997 bytes --]

[-- Attachment #3: throw-emacs-info-gloss-face-until+NO-def.png --]
[-- Type: image/png, Size: 66006 bytes --]

[-- Attachment #4: throw-emacs-info-gloss-links-NOface+def.png --]
[-- Type: image/png, Size: 73413 bytes --]

^ permalink raw reply	[flat|nested] 58+ messages in thread

* bug#60587: Patch for adding links to symbols' help documentation
  2023-01-26 10:37               ` Eli Zaretskii
  2023-01-27  7:45                 ` Juri Linkov
  2023-01-27 22:21                 ` H. Dieter Wilhelm
@ 2023-02-01 21:26                 ` H. Dieter Wilhelm
  2 siblings, 0 replies; 58+ messages in thread
From: H. Dieter Wilhelm @ 2023-02-01 21:26 UTC (permalink / raw)
  To: Eli Zaretskii; +Cc: 60587, Stefan Monnier, Drew Adams

[-- Attachment #1: Type: text/plain, Size: 707 bytes --]

Eli Zaretskii <eliz@gnu.org> writes:

>> +         (is-info (and ifile
>> +                       (or (assoc-string (concat ifi ".info") ifiles)
>> +                           ;; the top info "dir" file
>> +                           (assoc-string (concat ifi ".info.gz") ifiles)
>> +                           ;; info files might be archived!
>> +                           (when pdir (string-match pdir ifile)))
>> +                       (not (assoc-string ifi ndocu)))))
>
> This should probably be extended to allow more extensions; see
> Info-suffix-list.

Please see the latest iteration of patches.

I'm now working on converting the toggle function to a minor-mode, as
Drew and Stefan suggested..


[-- Attachment #2: 0001-Info-providing-buttons-on-quoted-symbols-bug-60587.patch --]
[-- Type: text/x-diff, Size: 18180 bytes --]

From b927d91a1bac4330f8a3b0eeab1a9adf30c3786e Mon Sep 17 00:00:00 2001
From: Dieter Wilhelm <dieter@duenenhof-wilhelm.de>
Date: Wed, 25 Jan 2023 22:00:57 +0100
Subject: [PATCH] Info providing buttons on quoted symbols (bug#60587)

*lisp/info.el
---
 lisp/info.el | 401 +++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 401 insertions(+)

diff --git a/lisp/info.el b/lisp/info.el
index 035dff66e75..f5994bf6ce2 100644
--- a/lisp/info.el
+++ b/lisp/info.el
@@ -5510,6 +5510,407 @@ info--manual-names
 					     Info-directory-list
 					     (mapcar #'car Info-suffix-list))))))))
 
+\f
+;;; Commentary:
+
+;; The code below provides links of symbols (functions, variables, and
+;; faces) within Emacs' Info viewer to their builtin help
+;; documentation.  This linking is done when symbol names in texinfo
+;; documentation (like the Emacs- and Elisp manual) are:
+
+;; 1. Quoted symbol names like `symbol-name'.
+
+;; 2. Function names which are prefixed by M-x, for example M-x
+;; function-name or are quoted and prefixed, like `M-x function-name'.
+
+;; 3. Function names appearing behind the following forms, which
+;; occur, for example, in the Elisp manual:
+
+;;   -- Special Form: function-name
+;;   -- Command: ...
+;;   -- Function: ...
+;;   -- Macro: ...
+
+;; 4. And variables names behind the following text:
+
+;;   -- User Option: variable-name
+;;   -- Variable: ...
+
+;; In any case all symbol names must be known to Emacs, which means it
+;; is either a built-in, or its Lisp package is loaded for the current
+;; Emacs session, or the symbol is auto-loaded.
+
+;; You can follow the additional links with the usual Info
+;; keybindings.  The customisation variable
+;; `mouse-1-click-follows-link' is influencing the clicking behavior
+;; (and tooltips) of the links, the variable's default is 450 (milli
+;; seconds) setting it to nil means only clicking with mouse-2 is
+;; following the link (hint: Drew Adams).
+
+;; The link color of symbols - referencing their builtin documentation
+;; - is distinct from links which are referencing further Info
+;; documentation.
+
+;; Below code is checking if Info documents are relevant Elisp and
+;; Emacs related files to avoid false positives.  Please see the
+;; customization variable `info-none-emacs-or-elisp-documents'.
+
+;; The code uses mostly mechanisms from Emacs' lisp/help-mode.el file.
+
+\f
+;;; Code:
+
+(require 'button)
+(require 'cl-lib)
+(require 'help-mode)
+(require 'cl-seq)
+(require 'subr-x)
+
+(defcustom info-make-xref-flag t
+  "True (`t') means Emacs creates symbol link buttons in Info.
+Setting this variable to `nil' inhibits the creation of buttons
+on quoted symbols to their help strings.  Please see the function
+`info-make-xrefs' for further details."
+  :type '(choice (const :tag "Create link buttons" t)
+                 (const :tag "Do not create link buttons" nil))
+  :set (lambda (sym defs)
+         (custom-set-default sym defs)
+         (let ((fun  (if info-make-xref-flag
+                         #'add-hook
+                       #'remove-hook)))
+           (funcall fun 'Info-selection-hook
+                    'info-make-xrefs)))
+  :version "30.1"
+  :group 'info)
+
+;; Toggle on or off the linking to help documents
+(when info-make-xref-flag
+  ;; Info-selection-hook runs when a node is selected
+  (add-hook 'Info-selection-hook 'info-make-xrefs))
+
+;; TODO: add this toggle in info documentation and NEWS
+;; TODO: remove and create buttons in current info buffer
+(defun info-toggle-make-xrefs ()
+  "Toggle creating Info buttons."
+  (interactive)
+  (if (memq 'info-make-xrefs Info-selection-hook)
+      (remove-hook 'Info-selection-hook 'info-make-xrefs)
+    (add-hook 'Info-selection-hook 'info-make-xrefs)
+    (message "Create Info link buttons to symbol names.")))
+
+(defvar info-emacs-info-dir-content nil
+  "List of file names in Emacs' info directories.
+It is used to check if the current info file `Info-current-file'
+belongs to the Emacs and Elisp context.  This variable will be
+initialised when opening the first info file.")
+
+(defcustom info-none-emacs-or-elisp-documents
+  '("aarm2012"   ; Ada manual from package "ada-ref-man", 2023 on Elpa
+    "aarm2020"   ; Ada manual from package "ada-ref-man", 2023 on Elpa
+    "arm2012"    ; Ada manual from package "ada-ref-man", 2023 on Elpa
+    "arm2020"    ; Ada manual from package "ada-ref-man", 2023 on Elpa
+    "sicp"       ; Structure and Interpretation of Computer Programs,
+                                        ; package "sicp" 2023 on Melpa archive
+    )
+  "List of documentation which is not related to GNU Emacs or Elisp.
+As well as documents which should not be searched for linking to
+help documentation, for more details please see
+`info-check-docu-p'.  The list must contain only the base name of
+info files, e.g. without the file extension \".info\"."
+  :type '(repeat string)
+  :version "30.1"
+  :group 'info)
+
+(defun info-check-docu-p ()
+  "Check if the current info file is relevant to Emacs or Elisp.
+That means `Info-current-file' is either found in Emacs' info/
+directory or in `package-user-dir' and is not included in the
+`info-none-emacs-or-elisp-documents' list."
+  (unless info-emacs-info-dir-content
+    (info-compile-emacs-info-dir-content))
+  (let* ((ifile Info-current-file) ;I-c-f doesn't yield file suffices!
+         (ifi (file-name-nondirectory ifile))
+         ;; Verify that checking pdir is redundant because Package
+         ;; adds info package folders to Info-directory-list
+         (pdir (when (boundp 'package-user-dir)
+                 (expand-file-name
+                  package-user-dir)))
+         (ifiles info-emacs-info-dir-content)
+         (ndocu info-none-emacs-or-elisp-documents)
+         (sufs (mapcar 'car Info-suffix-list))
+         (vars (mapcar #'(lambda (x)(concat ifi x)) sufs))
+         (emacsy (and ifile
+                      (or (cl-intersection vars ifiles :test #'string=)
+                          (when pdir (string-match pdir ifile)))
+                      (not (assoc-string ifi ndocu)))))
+    (if emacsy
+        t)))
+
+(defvar describe-symbol-backends)      ;from help-mode.el
+(defvar help-xref-following)           ;dito
+
+(defvar-keymap info-button-map
+  :doc "Keymap used by buttons in Info buffers."
+  "RET" #'push-button
+  "<mouse-2>" #'push-button
+  "<follow-link>" 'mouse-face
+  "<mode-line> <mouse-2>" #'push-button
+  "<header-line> <mouse-2>" #'push-button)
+
+;; Button types
+
+;; Below parent button inherits Info's quoted symbol face
+;; `Info-quoted'.  Otherwise the buttons would inherit from
+;; button.el's `link' face which looks identical to Info's links.  I
+;; think it is helpful to distinguish both link types because they
+;; also act differently.
+(define-button-type 'info
+  'link t
+  'follow-link t
+  'face 'Info-quoted
+  'keymap info-button-map
+  'action #'info-button-action)
+
+(define-button-type 'info-function
+  :supertype 'info
+  'info-function 'describe-function
+  'help-echo (purecopy "mouse-2, RET: describe this function"))
+
+(define-button-type 'info-variable
+  :supertype 'info
+  'info-function 'describe-variable
+  'help-echo (purecopy "mouse-2, RET: describe this variable"))
+
+(define-button-type 'info-face
+  :supertype 'info
+  'info-function 'describe-face
+  'help-echo (purecopy "mouse-2, RET: describe this face"))
+
+(define-button-type 'info-symbol
+  :supertype 'info
+  'info-function #'describe-symbol
+  'help-echo (purecopy "mouse-2, RET: describe this symbol"))
+
+(define-button-type 'info-function-def
+  :supertype 'info
+  'info-function (lambda (fun &optional file type)
+                   (or file
+                       (setq file (find-lisp-object-file-name fun type)))
+                   (if (not file)
+                       (message "Unable to find defining file")
+                     (require 'find-func)
+                     (when (eq file 'C-source)
+                       (setq file
+                             (help-C-file-name (indirect-function fun) 'fun)))
+                     ;; Don't use find-function-noselect because it follows
+                     ;; aliases (which fails for built-in functions).
+                     (let ((location
+                            (find-function-search-for-symbol fun type file)))
+                       (pop-to-buffer (car location))
+                       (run-hooks 'find-function-after-hook)
+                       (if (cdr location)
+                           (goto-char (cdr location))
+                         (message "Unable to find location in file")))))
+  'help-echo (purecopy "mouse-2, RET: find function's definition"))
+
+(defun info-compile-emacs-info-dir-content ()
+  "Build a list of file names from Emacs' info directories.
+This function fills `info-emacs-info-dir-content' with files from
+`Info-directory-list'."
+  (setq info-emacs-info-dir-content
+        (mapcar 'file-name-nondirectory
+                (directory-files
+                 (car
+                  ;; search for the main Emacs' info/ directory, when this
+                  ;; function is called Info-directory-list is already
+                  ;; initialised
+                  (cl-member "[^.]emacs" Info-directory-list :test
+                             'string-match-p))
+                 ;; don't list "." and ".."
+                 t  "[^.]$"))))
+
+(defun info-button-action (button)
+  "Call BUTTON's help function."
+  (info-do-xref nil
+                (button-get button 'info-function)
+                (button-get button 'info-args)))
+
+(defun info-do-xref (_pos function args)
+  "Call the help cross-reference function FUNCTION with args ARGS.
+Things are set up properly so that the resulting `help-buffer' has
+a proper [back] button."
+  ;; There is a reference at point.  Follow it.
+  (let ((help-xref-following nil))
+    (apply
+     function (if (eq function 'info)
+                  (append args (list (generate-new-buffer-name "*info*")))args))))
+
+(defun info-button (match-number type &rest args)
+  "Make a hyperlink for cross-reference text previously matched.
+MATCH-NUMBER is the subexpression of interest in the last matched
+regexp.  TYPE is the type of button to use.  Any remaining
+arguments are passed to the button's info-function when it is
+invoked.  See `info-make-xrefs'.  Don't forget ARGS."
+  ;; Don't munge properties we've added, especially in some instances.
+  (unless (button-at (match-beginning match-number))
+    (make-text-button (match-beginning match-number)
+                      (match-end match-number)
+                      'type type 'info-args args)))
+
+(defvar info-symbol-context
+  '((variable . "variable\\|option")
+    (function . "function\\|command\\|call")
+    (face . "face")
+    ;; ignore symbols following this context type
+    (ignore . "symbol\\|program\\|property")
+    ;; function definitions in files
+    (definition . "source \\(?:code \\)?\\(?:of\\|for\\)"))
+  "This list helps to distinguish symbol types.
+Words in info documentation preceding a (quoted) symbol are used
+to distinguish variables, functions, faces and symbols.  The
+context information can also be used to ignore symbols because
+there is no help documentation for them.  The strings of the the
+list are becoming part of `info-symbol-regexp'.")
+
+(defvar info-symbol-regexp
+  ;; use purecopy?
+  (concat
+   "\\("                                ; Context start
+   "\\<\\("                             ; Contex type definition
+   (string-remove-suffix
+    "\\|"
+    (mapconcat
+     (lambda (x) (concat "\\(" (cdr x) "\\)\\|"))
+     info-symbol-context ""))
+   "\\)"          ; Context type definition end
+   "[ \t\n]+"     ; Separators to quoted symbols
+   "\\)?"         ; End of context
+   ;; quoted symbol
+   "['`‘]"	  ; opening quotes
+   ;; Note: Symbol starting with word-syntax character:
+   "\\(\\sw\\(\\sw\\|\\s_\\)+\\|`\\)" ; The symbol itself
+   "['’]"                             ; End quotes
+   )
+  "The regular expression for matching symbols to their help documentation.
+It is comprised of the symbol's context and the (quoted) symbol
+name.  The various groups of context regular expressions are
+matched in `info-make-xrefs' to distinct info buttons.")
+
+(defun info-check-type( type)
+  "Check if TYPE corresponds to the current search result.
+The function is used in `info-make-xrefs'."
+  (let* ((isc info-symbol-context)
+	 (n 3)                           ;embedded within 2 groups
+         (l (+ 3 (length isc))))
+    (while (and (not (eq type (caar isc) ) ) (< n l) )
+      (setq n (1+ n))
+      (setq isc (cdr isc)))
+    (match-string n)))
+
+\f
+;;;###autoload
+(defun info-make-xrefs (&optional buffer)
+  "Parse and hyperlink documentation cross-references in the given BUFFER.
+BUFFER defaults to the current buffer if omitted or nil.  Find
+cross-reference information in a buffer and activate such cross
+references for selection with `help-follow'.
+
+ Cross-references have the canonical (quoted) form `symbol-name'
+and the type of reference may be disambiguated by the preceding
+word(s) as compiled in `info-symbol-regexp'.  For example: Symbol
+names are receiving distinct variable buttons when preceeded by
+the words \"variable\" or \"option\".
+
+Variables are also detected when their names follow below form:
+
+ -- User Option: variable-name
+ -- Variable: ...
+
+Function names are also detected when prefixed by `M-x', for
+example `M-x function-name' or are quoted and prefixed like `M-x
+function-name'.
+
+Function names are detected, as well, when appearing behind the
+following forms, which occur - for example - in the Elisp manual:
+
+ -- Special Form: function-name
+ -- Command: ...
+ -- Function: ...
+ -- Macro: ...
+
+The linking is similar to mechanisms from lisp/help.el."
+  (interactive "b")
+  (when (info-check-docu-p)
+    (with-current-buffer (or buffer (current-buffer))
+      (save-excursion
+        (goto-char (point-min))
+        (with-silent-modifications      ;hint from Stefan
+          (let ((case-fold-search t)
+                (inhibit-read-only t))
+            (with-syntax-table emacs-lisp-mode-syntax-table
+              ;; Quoted symbols
+              (save-excursion
+                (while (re-search-forward info-symbol-regexp nil t)
+                  (let* ((sym-group (+ 3 (length info-symbol-context)))
+                         (data (match-string sym-group))
+                         (sym (intern-soft data)))
+                    (if sym
+                        (cond
+                         ((info-check-type 'variable)
+                          (and (or (boundp sym)
+                                   (get sym 'variable-documentation))
+                               (info-button sym-group 'info-variable sym)))
+                         ((info-check-type 'function)
+                          (and (fboundp sym)
+                               (info-button sym-group 'info-function sym)))
+                         ((info-check-type 'face)
+                          (and (facep sym)
+                               (info-button sym-group 'info-face sym)))
+                         ((info-check-type 'ignore))
+                         ((info-check-type 'definition)
+                          (info-button sym-group 'info-function-def sym))
+                         ;; symbols
+                         ((cl-some (lambda (x) (funcall (nth 1 x) sym))
+                                   describe-symbol-backends)
+                          (info-button sym-group 'info-symbol sym)))))))
+              ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+              ;; (info "(elisp) Eval")
+              ;; Elisp manual      -- Special Form:
+              ;;                   -- Command:
+              ;;                   -- Function: function-name function
+              ;;                   -- Macro:
+              (save-excursion
+                (while (re-search-forward
+                        "-- \\(Special Form:\\|Command:\\|Function:\\|Macro:\\) "
+                        nil t)
+                  (looking-at "\\(\\sw\\|\\s_\\)+")
+                  (let ((sym (intern-soft (match-string 0))))
+                    (if (fboundp sym)
+                        (info-button 0 'info-function sym)))))
+              ;;              -- User Option:
+              ;;              -- Variable: variable-name
+              (save-excursion
+                (while (re-search-forward
+                        "-- \\(User Option:\\|Variable:\\) "
+                        nil t)
+                  (looking-at "\\(\\sw\\|\\s_\\)+")
+                  (let ((sym (intern-soft (match-string 0))))
+                    (if (boundp sym)
+                        (info-button 0 'info-variable sym)))))
+              ;; M-x prefixed functions
+              (save-excursion
+                (while (re-search-forward
+                        ;; Assume command name is only word and symbol
+                        ;; characters to get things like `use M-x foo->bar'.
+                        ;; Command required to end with word constituent
+                        ;; to avoid `.' at end of a sentence.
+                        ;; "\\<M-x\\s-+\\(\\sw\\(\\sw\\|\\s_\\)*\\sw\\)" nil t)
+                        ;; include M-x and quotes
+                        "['`‘]?M-x\\s-*\n?\\(\\sw\\(\\sw\\|\\s_\\)*\\sw\\)['’]?" nil t)
+                  (let ((sym (intern-soft (match-string 1))))
+                    (if (fboundp sym)
+                        (info-button 1 'info-function sym))))))))))))
+
 (provide 'info)
 
 ;;; info.el ends here
-- 
2.34.1


[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #3: 0001-Documentation-of-Info-providing-buttons-on-quoted-sy.patch --]
[-- Type: text/x-diff, Size: 2291 bytes --]

From eaf3ad409e1ec29bb1207db44e17fa27cda0f5d2 Mon Sep 17 00:00:00 2001
From: Dieter Wilhelm <dieter@duenenhof-wilhelm.de>
Date: Wed, 1 Feb 2023 22:01:19 +0100
Subject: [PATCH] Documentation of Info providing buttons on quoted symbols
 (bug#60587)

* doc/emacs/help.texi
* etc/NEWS
---
 doc/emacs/help.texi | 13 +++++++++++++
 etc/NEWS            | 11 +++++++++++
 2 files changed, 24 insertions(+)

diff --git a/doc/emacs/help.texi b/doc/emacs/help.texi
index 2513e6be271..18a223b228f 100644
--- a/doc/emacs/help.texi
+++ b/doc/emacs/help.texi
@@ -653,6 +653,19 @@ Misc Help
 K @var{key}}, described above, enter Info and go straight to the
 documentation of @var{function} or @var{key}.
 
+  Info makes quoted symbol names into buttons which show the symbols'
+help documentation when typing @key{RET} or clicking the mouse
+(@pxref{Mouse References}).  For example, the quoted name
+@code{info-other-window} is made into a button which shows the
+function's documentation string in another window, in the
+@file{*Help*} buffer.  Info highlights such quoted symbols (variables,
+functions and face names) by a distinct face and these can be reached,
+as regular Info manual references, with @key{TAB} and @kbd{S-Tab}.
+
+@vindex info-make-xref-flag
+  If you want to prohibit the button creation for Info buffers, you
+can set @code{info-make-xref-flag} to @code{nil}.
+
 @kindex C-h S
 @findex info-lookup-symbol
   When editing a program, if you have an Info version of the manual
diff --git a/etc/NEWS b/etc/NEWS
index 5b8ab06086c..c55d39baf0c 100644
--- a/etc/NEWS
+++ b/etc/NEWS
@@ -195,6 +195,17 @@ This command adds a docstring comment to the current defun.  If a
 comment already exists, point is only moved to the comment.  It is
 bound to 'C-c C-d' in 'go-ts-mode'.
 
+** Info
+
++++
+*** Info-mode provides buttons on symbols showing their documentation string.
+Quoted `symbols', like names of variables, functions or face names,
+are made into buttons which can display the respective documentation
+strings.  These strings are presented in *Help* buffers in another
+window.  Such buttons are working independently of the regular Info
+cross references and can be disabled with setting
+`info-make-xref-flag' to nil.
+
 \f
 * New Modes and Packages in Emacs 30.1
 
-- 
2.34.1


[-- Attachment #4: Type: text/plain, Size: 57 bytes --]



-- 
Best wishes
H. Dieter Wilhelm
Zwingenberg, Germany

^ permalink raw reply related	[flat|nested] 58+ messages in thread

* bug#60587: Patch for adding links to symbols' help documentation
  2023-01-27 23:13                   ` Drew Adams
  2023-01-28  8:11                     ` Eli Zaretskii
@ 2023-02-01 22:09                     ` H. Dieter Wilhelm
  2023-02-02  2:30                       ` Drew Adams
  2023-02-05  0:48                     ` H. Dieter Wilhelm
  2 siblings, 1 reply; 58+ messages in thread
From: H. Dieter Wilhelm @ 2023-02-01 22:09 UTC (permalink / raw)
  To: Drew Adams; +Cc: Eli Zaretskii, 60587@debbugs.gnu.org, monnier@iro.umontreal.ca

Hi Drew

Drew Adams <drew.adams@oracle.com> writes:

>> > 1.
>> > +  :type '(choice (const :tag "Create links" t)
>> > +                 (const :tag "Do not link" nil))
>> >
>> > is better as just :type 'boolean, and say in the
>> > doc which Boolean value means which behavior.
>> 
>> The doc string says now:
>> 
>>   "True (`t') means Emacs creates symbol link buttons in Info.
>> Setting this variable to `nil' inhibits the creation of buttons
>> on quoted symbols to their help strings.  Please see the function
>> `info-make-xrefs' for further details."
>
> Is the defcustom now :type 'boolean?

Please tell me why you insist now on changing the :type from choice to
boolean?  Above you stated that it "is better than just :type boolean"!?

I experimented in `customize' with :type 'boolean and the "toggle"
button is fast and easy.  On the other hand with 'choice I think the
alternatives are clearer documented while changing it's values..

>> > 4. Or instead of having an option, maybe just have
>> > a minor mode.
>> 
>> That's also a nice idea.  (Maybe for later.)
>
> See Stefan's reply...

Alright, I'm going in this direction but I'm not so fast.  😅

>> > 6. "clicking @kbd{mouse-2} or @kbd{mouse-1} on it"
>> > can't be right, I think.  At least that doesn't
>> > express what `mouse-1-follows-link' does/means.

On the suggestion of Eli, I just stated `mouse' and added a cross
reference, ahem, link to the mouse manual section.

Thanks for your interest

       Dieter
-- 
Best wishes
H. Dieter Wilhelm
Zwingenberg, Germany





^ permalink raw reply	[flat|nested] 58+ messages in thread

* bug#60587: Patch for adding links to symbols' help documentation
  2023-02-01 22:09                     ` H. Dieter Wilhelm
@ 2023-02-02  2:30                       ` Drew Adams
  0 siblings, 0 replies; 58+ messages in thread
From: Drew Adams @ 2023-02-02  2:30 UTC (permalink / raw)
  To: H. Dieter Wilhelm
  Cc: Eli Zaretskii, 60587@debbugs.gnu.org, monnier@iro.umontreal.ca

> Drew Adams <drew.adams@oracle.com> writes:
> 
> >> > 1.
> >> > +  :type '(choice (const :tag "Create links" t)
> >> > +                 (const :tag "Do not link" nil))
> >> >
> >> > is better as just :type 'boolean, and say in the
> >> > doc which Boolean value means which behavior.
> >>
> >> The doc string says now:
> >>
> >>   "True (`t') means Emacs creates symbol link buttons in Info.
> >> Setting this variable to `nil' inhibits the creation of buttons
> >> on quoted symbols to their help strings.  Please see the function
> >> `info-make-xrefs' for further details."
> >
> > Is the defcustom now :type 'boolean?
> 
> Please tell me why you insist now on changing the :type from choice to
> boolean?  Above you stated that it "is better than just :type boolean"!?

Misunderstanding.

1. I don't insist on anything.
2. I didn't say "is better than"; I said "is better as".

For #2: Sorry, I should have been less succinct.
I meant that (I think) that a `choice' such as what
you presented is simpler _as_ a `boolean' instead.
IOW, a boolean def is simpler.  I should have said
it that way.

> I experimented in `customize' with :type 'boolean and the "toggle"
> button is fast and easy.  On the other hand with 'choice I think the
> alternatives are clearer documented while changing it's values..

Yes, with `boolean' you can't specify a :tag.
But usually the doc string (which is also shown
in Customize) makes clear what each value does/means.

It was a minor comment.  There's nothing wrong with
using `choice' as you did.  Sorry for the noise.

> >> > 4. Or instead of having an option, maybe just have
> >> > a minor mode.
> >>
> >> That's also a nice idea.  (Maybe for later.)
> >
> > See Stefan's reply...
> 
> Alright, I'm going in this direction but I'm not so fast.  😅

There's no hurry.

> >> > 6. "clicking @kbd{mouse-2} or @kbd{mouse-1} on it"
> >> > can't be right, I think.  At least that doesn't
> >> > express what `mouse-1-follows-link' does/means.
> 
> On the suggestion of Eli, I just stated `mouse' and added a cross
> reference, ahem, link to the mouse manual section.
> 
> Thanks for your interest

Thanks for working on this.
____

FWIW, I disagree with Eli here.  I think saying
which mouse button to use is better than just
saying click the mouse.  And which button to
click is taken care of automatically, if you use
\\[mouse-2], as you pointed out.
____

FWIW2: If `mouse-1-click-follows-link' is nil
then you can click `mouse-1' on a link to set
point there.  That's the advantage of that choice
(and it was what Emacs used to do by default).

If the value is non-nil then a user can click
mouse-1 to follow links, which is an advantage
in being what users are used to in browsers.
(With a non-nil value you have to press and hold
mouse-1 for a bit, to set point there.)

Since `mouse-2' is for yanking normally, and
since contexts where there are links typically
don't also allow yanking, the classic Emacs
approach was (still is) a smart one.

And in an editor I, at least, more often want
to use the mouse to set point, even on links -
more often than I want to yank with the mouse
in contexts that have links.  I prefer the old
default behavior, and I think Emacs should have
stuck with it.



^ permalink raw reply	[flat|nested] 58+ messages in thread

* bug#60587: Patch for adding links to symbols' help documentation
  2023-01-27 23:13                   ` Drew Adams
  2023-01-28  8:11                     ` Eli Zaretskii
  2023-02-01 22:09                     ` H. Dieter Wilhelm
@ 2023-02-05  0:48                     ` H. Dieter Wilhelm
  2023-02-05  3:54                       ` Stefan Monnier via Bug reports for GNU Emacs, the Swiss army knife of text editors
  2 siblings, 1 reply; 58+ messages in thread
From: H. Dieter Wilhelm @ 2023-02-05  0:48 UTC (permalink / raw)
  To: Drew Adams; +Cc: Eli Zaretskii, 60587@debbugs.gnu.org, monnier@iro.umontreal.ca

[-- Attachment #1: Type: text/plain, Size: 761 bytes --]

Tags: patch

Drew Adams <drew.adams@oracle.com> writes:

>> > 4. Or instead of having an option, maybe just have
>> > a minor mode.
>> 
>> That's also a nice idea.  (Maybe for later.)
>
> See Stefan's reply...

I rewrote the former toggle as a minor mode and also wanted to implement
the mode's variable as a defcustom but I couldn't figure out to avoid
then that the mode is assigned to every buffer!  (By the way, the
information in the manual (info "(elisp) Minor Modes") is not very
enlightening in this respect because the mentioned Diff Auto Refine mode
-- specific to a major mode -- is since Emacs-27 obsolete and, it seems,
now changed from it's original implementation..)

Please check a further iteration of patches for buttonising Info.

Thank you


[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: 0001-Documentation-of-Info-providing-buttons-on-quoted-sy.patch --]
[-- Type: text/x-diff, Size: 2321 bytes --]

From 963e018503b7e1703480c527d48c2b119842f8f0 Mon Sep 17 00:00:00 2001
From: Dieter Wilhelm <dieter@duenenhof-wilhelm.de>
Date: Wed, 1 Feb 2023 22:01:19 +0100
Subject: [PATCH] Documentation of Info providing buttons on quoted symbols
 (bug#60587)

* doc/emacs/help.texi
* etc/NEWS
---
 doc/emacs/help.texi | 15 +++++++++++++++
 etc/NEWS            | 10 ++++++++++
 2 files changed, 25 insertions(+)

diff --git a/doc/emacs/help.texi b/doc/emacs/help.texi
index 2513e6be271..8aeb4068319 100644
--- a/doc/emacs/help.texi
+++ b/doc/emacs/help.texi
@@ -653,6 +653,21 @@ Misc Help
 K @var{key}}, described above, enter Info and go straight to the
 documentation of @var{function} or @var{key}.
 
+@vindex info-button-mode
+  The minor mode @code{info-button-mode} makes quoted symbol names
+into buttons which show the symbols' documentation string when typing
+@key{RET} or clicking the mouse (@pxref{Mouse References}).  For
+example, the quoted name @code{info-other-window} is made into a
+button which shows the function's documentation string in another
+window, in the @file{*Help*} buffer.  Info highlights such quoted
+symbols (variables, functions and face names) by a distinct face and
+these can be reached, as regular Info manual references, with
+@key{TAB} and @kbd{S-Tab}.
+
+  If you want to remove these buttons, you can toggle the mode with
+typing @kbd{M-x info-button-mode} or deactivating it with
+@code{(info-button-mode -1)} in Emacs' initialisation file.
+
 @kindex C-h S
 @findex info-lookup-symbol
   When editing a program, if you have an Info version of the manual
diff --git a/etc/NEWS b/etc/NEWS
index 5b8ab06086c..96637797358 100644
--- a/etc/NEWS
+++ b/etc/NEWS
@@ -195,6 +195,16 @@ This command adds a docstring comment to the current defun.  If a
 comment already exists, point is only moved to the comment.  It is
 bound to 'C-c C-d' in 'go-ts-mode'.
 
+** Info
+
++++
+*** New minor mode 'info-button-mode'
+This mode provides buttons on symbols showing their documentation
+string in *Help* buffers (in another window) when typing `RET' or
+clicking `mouse-2'.  These buttons are working independently of the
+regular Info cross references and can be toggled with `M-x
+info-button-mode' or disabled with `(info-button-mode -1)'.
+
 \f
 * New Modes and Packages in Emacs 30.1
 
-- 
2.34.1


[-- Attachment #3: 0001-Info-providing-buttons-on-quoted-symbols-bug-60587.patch --]
[-- Type: text/x-diff, Size: 18233 bytes --]

From 16453b420ca272b9139568d54c7b47e551ced8e8 Mon Sep 17 00:00:00 2001
From: Dieter Wilhelm <dieter@duenenhof-wilhelm.de>
Date: Wed, 25 Jan 2023 22:00:57 +0100
Subject: [PATCH] Info providing buttons on quoted symbols (bug#60587)

*lisp/info.el
---
 lisp/info.el | 401 +++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 401 insertions(+)

diff --git a/lisp/info.el b/lisp/info.el
index 035dff66e75..0496259353b 100644
--- a/lisp/info.el
+++ b/lisp/info.el
@@ -5510,6 +5510,407 @@ info--manual-names
 					     Info-directory-list
 					     (mapcar #'car Info-suffix-list))))))))
 
+\f
+;;; Commentary:
+
+;; All code below provides buttons of symbols (functions, variables,
+;; and faces) within Emacs' Info viewer linking to their builtin help
+;; documentation.  This linking is done when symbol names in texinfo
+;; documentation (like the Emacs- and Elisp manual) are:
+
+;; 1. Quoted symbol names like `symbol-name'.
+
+;; 2. Function names which are prefixed by M-x, for example M-x
+;; function-name or are quoted and prefixed, like `M-x function-name'.
+
+;; 3. Function names appearing behind the following forms, which
+;; occur, for example, in the Elisp manual: (info "(elisp) Eval")
+
+;;   -- Special Form: function-name
+;;   -- Command: ...
+;;   -- Function: ...
+;;   -- Macro: ...
+
+;; 4. And variables names behind the following text:
+
+;;   -- User Option: variable-name
+;;   -- Variable: ...
+
+;; In any case all symbol names must be known to Emacs, which means it
+;; is either a built-in, or its Lisp package is loaded for the current
+;; Emacs session, or the symbol is auto-loaded.
+
+;; You can follow the additional links with the usual Info
+;; keybindings.  The customisation variable
+;; `mouse-1-click-follows-link' is influencing the clicking behavior
+;; (and tooltips) of the links, the variable's default is 450 (milli
+;; seconds) setting it to nil means only clicking with mouse-2 is
+;; following the link (hint: Drew Adams).
+
+;; The link color of symbols - referencing their builtin documentation
+;; - is distinct from links which are referencing further Info
+;; documentation.
+
+;; Below code is checking if Info documents are relevant Elisp and
+;; Emacs related files to avoid false positives.  Please see the
+;; customization variable `info-none-emacs-or-elisp-documents'.
+
+;; The code uses mostly mechanisms from Emacs' lisp/help-mode.el file.
+
+\f
+;;; Code:
+
+(require 'button)
+(require 'cl-lib)
+(require 'help-mode)
+(require 'cl-seq)
+(require 'subr-x)
+
+(define-minor-mode info-button-mode
+  "The mode creates buttons on symbols linking to their help documentation.
+
+"
+  :init-value nil
+  :lighter " B"
+  :group 'info
+  :version "30.1"
+  (if (string= major-mode "Info-mode")
+      (if info-button-mode
+          (progn
+            (add-hook 'Info-selection-hook 'info-make-button)
+            (info-make-button))               ;for the current buffer
+        (remove-hook 'Info-selection-hook 'info-make-button)
+        (setq inhibit-read-only t)
+        (remove-list-of-text-properties (point-min) (point-max)
+                                        '(button category info-args))
+        (set-buffer-modified-p nil))
+    (setq info-button-mode nil)))
+;; No defcustom for i-b-m since it activates it then for all buffers
+
+;; Activate the mode for all Info buffers
+(add-hook 'Info-mode-hook 'info-button-mode)
+
+(defvar info-emacs-info-dir-content nil
+  "List of file names in Emacs' info directories.
+It is used to check if the current info file `Info-current-file'
+belongs to the Emacs and Elisp context.  This variable will be
+initialised when opening the first info file.")
+
+(defcustom info-none-emacs-or-elisp-documents
+  '("aarm2012"   ; Ada manual from package "ada-ref-man", 2023 on Elpa
+    "aarm2020"   ; Ada manual from package "ada-ref-man", 2023 on Elpa
+    "arm2012"    ; Ada manual from package "ada-ref-man", 2023 on Elpa
+    "arm2020"    ; Ada manual from package "ada-ref-man", 2023 on Elpa
+    "sicp"       ; Structure and Interpretation of Computer Programs,
+                                        ; package "sicp" 2023 on Melpa archive
+    )
+  "List of documentation which is not related to GNU Emacs or Elisp.
+As well as documents which should not be searched for linking to
+help documentation, for more details please see
+`info-check-docu-p'.  The list must contain only the base name of
+info files, e.g. without the file extension \".info\"."
+  :type '(repeat string)
+  :version "30.1"
+  :group 'info)
+
+(defun info-check-docu-p ()
+  "Check if the current info file is relevant to Emacs or Elisp.
+That means `Info-current-file' is either found in Emacs' info/
+directory or in `package-user-dir' and is not included in the
+`info-none-emacs-or-elisp-documents' list."
+  ;; When initialising Info and `Info-mode-hook' is running there is
+  ;; not yet `Info-current-file' initialised
+  (when Info-current-file
+    (unless info-emacs-info-dir-content
+      (info-compile-emacs-info-dir-content))
+    (let* ((ifile Info-current-file) ;I-c-f doesn't yield file suffices!
+           (ifi (file-name-nondirectory ifile))
+           ;; Verify that checking pdir is redundant because Package
+           ;; adds info package folders to Info-directory-list
+           (pdir (when (boundp 'package-user-dir)
+                   (expand-file-name
+                    package-user-dir)))
+           (ifiles info-emacs-info-dir-content)
+           (ndocu info-none-emacs-or-elisp-documents)
+           (sufs (mapcar 'car Info-suffix-list))
+           (vars (mapcar #'(lambda (x)(concat ifi x)) sufs))
+           (emacsy (and ifile
+                        (or (cl-intersection vars ifiles :test #'string=)
+                            (when pdir (string-match pdir ifile)))
+                        (not (assoc-string ifi ndocu)))))
+      (if emacsy
+          t))))
+
+(defvar describe-symbol-backends)      ;from help-mode.el
+(defvar help-xref-following)           ;dito
+
+(defvar-keymap info-button-map
+  :doc "Keymap used by buttons in Info buffers."
+  "RET" #'push-button
+  "<mouse-2>" #'push-button
+  "<follow-link>" 'mouse-face
+  "<mode-line> <mouse-2>" #'push-button
+  "<header-line> <mouse-2>" #'push-button)
+
+;;
+;; Button types
+;;
+
+;; Below parent button type `info' inherits Info's quoted symbol face
+;; `Info-quoted'.  Otherwise the buttons would inherit from
+;; button.el's `link' face which looks identical to Info's links.  But
+;; I think it is helpful to distinguish between button link and cross
+;; reference types because they react differently.
+(define-button-type 'info
+  'link t
+  'follow-link t
+  'face 'Info-quoted
+  'keymap info-button-map
+  'action #'info-button-action)
+
+(define-button-type 'info-function
+  :supertype 'info
+  'info-function 'describe-function
+  'help-echo (purecopy "mouse-2, RET: describe this function"))
+
+(define-button-type 'info-variable
+  :supertype 'info
+  'info-function 'describe-variable
+  'help-echo (purecopy "mouse-2, RET: describe this variable"))
+
+(define-button-type 'info-face
+  :supertype 'info
+  'info-function 'describe-face
+  'help-echo (purecopy "mouse-2, RET: describe this face"))
+
+(define-button-type 'info-symbol
+  :supertype 'info
+  'info-function #'describe-symbol
+  'help-echo (purecopy "mouse-2, RET: describe this symbol"))
+
+(define-button-type 'info-function-def
+  :supertype 'info
+  'info-function (lambda (fun &optional file type)
+                   (or file
+                       (setq file (find-lisp-object-file-name fun type)))
+                   (if (not file)
+                       (message "Unable to find defining file")
+                     (require 'find-func)
+                     (when (eq file 'C-source)
+                       (setq file
+                             (help-C-file-name (indirect-function fun) 'fun)))
+                     ;; Don't use find-function-noselect because it follows
+                     ;; aliases (which fails for built-in functions).
+                     (let ((location
+                            (find-function-search-for-symbol fun type file)))
+                       (pop-to-buffer (car location))
+                       (run-hooks 'find-function-after-hook)
+                       (if (cdr location)
+                           (goto-char (cdr location))
+                         (message "Unable to find location in file")))))
+  'help-echo (purecopy "mouse-2, RET: find function's definition"))
+
+(defun info-compile-emacs-info-dir-content ()
+  "Build a list of file names from Emacs' info directories.
+This function fills `info-emacs-info-dir-content' with files from
+`Info-directory-list'."
+  (setq info-emacs-info-dir-content
+        (mapcar 'file-name-nondirectory
+                (directory-files
+                 (car
+                  ;; search for the main Emacs' info/ directory, when this
+                  ;; function is called Info-directory-list is already
+                  ;; initialised
+                  (cl-member "[^.]emacs" Info-directory-list :test
+                             'string-match-p))
+                 ;; don't list "." and ".."
+                 t  "[^.]$"))))
+
+(defun info-button-action (button)
+  "Call BUTTON's help function."
+  (info-do-xref nil
+                (button-get button 'info-function)
+                (button-get button 'info-args)))
+
+(defun info-do-xref (_pos function args)
+  "Call the help cross-reference function FUNCTION with args ARGS.
+Things are set up properly so that the resulting `help-buffer' has
+a proper [back] button."
+  ;; There is a reference at point.  Follow it.
+  (let ((help-xref-following nil))
+    (apply
+     function (if (eq function 'info)
+                  (append args (list (generate-new-buffer-name "*info*")))args))))
+
+(defun info-button (match-number type &rest args)
+  "Make a hyperlink for cross-reference text previously matched.
+MATCH-NUMBER is the subexpression of interest in the last matched
+regexp.  TYPE is the type of button to use.  Any remaining
+arguments are passed to the button's info-function when it is
+invoked.  See `info-make-button'.  Don't forget ARGS."
+  ;; Don't munge properties we've added, especially in some instances.
+  (unless (button-at (match-beginning match-number))
+    (make-text-button (match-beginning match-number)
+                      (match-end match-number)
+                      'type type 'info-args args)))
+
+(defvar info-symbol-context
+  '((variable . "variable\\|option")
+    (function . "function\\|command\\|call")
+    (face . "face")
+    ;; ignore symbols following this context type
+    (ignore . "symbol\\|program\\|property")
+    ;; function definitions in files
+    (definition . "source \\(?:code \\)?\\(?:of\\|for\\)"))
+  "This list helps to distinguish symbol types.
+Words in info documentation preceding a (quoted) symbol are used
+to distinguish variables, functions, faces and symbols.  The
+context information can also be used to ignore symbols because
+there is no help documentation for them.  The strings of the the
+list are becoming part of `info-symbol-regexp'.")
+
+(defvar info-symbol-regexp
+  ;; better use purecopy?
+  (concat
+   "\\("                                ; Context start
+   "\\<\\("                             ; Contex type definition
+   (string-remove-suffix
+    "\\|"
+    (mapconcat
+     (lambda (x) (concat "\\(" (cdr x) "\\)\\|"))
+     info-symbol-context ""))
+   "\\)"          ; Context type definition end
+   "[ \t\n]+"     ; Separators to quoted symbols
+   "\\)?"         ; End of context
+   ;; quoted symbol
+   "['`‘]"	  ; opening quotes
+   ;; Note: Symbol starting with word-syntax character:
+   "\\(\\sw\\(\\sw\\|\\s_\\)+\\|`\\)" ; The symbol itself
+   "['’]"                             ; End quotes
+   )
+  "The regular expression for matching symbols to their help documentation.
+It is comprised of the symbol's context and the (quoted) symbol
+name.  The various groups of context regular expressions are
+matched in `info-make-button' to distinct info buttons.")
+
+(defun info-check-type( type)
+  "Check if TYPE corresponds to the current search result.
+The function is used in `info-make-button'."
+  (let* ((isc info-symbol-context)
+	 (n 3)                           ;embedded within 2 groups
+         (l (+ 3 (length isc))))
+    (while (and (not (eq type (caar isc) ) ) (< n l) )
+      (setq n (1+ n))
+      (setq isc (cdr isc)))
+    (match-string n)))
+
+\f
+;;;###autoload
+(defun info-make-button (&optional buffer)
+  "Parse and hyperlink quoted symbols in the given BUFFER.
+BUFFER defaults to the current buffer if omitted or nil.  Find
+symbols and their context in an Info buffer and activate buttons
+for linking to their documentation string with `info-button'.
+
+Symbols have the canonical (quoted) form `symbol-name' and the
+type of reference may be disambiguated by the preceding word(s)
+as compiled in `info-symbol-regexp'.  For example: Symbol names
+are receiving distinct variable buttons when preceeded by the
+words \"variable\" or \"option\".
+
+Variables are also detected when their names follow below forms:
+
+ -- User Option: variable-name
+ -- Variable: ...
+
+Function names are detected when prefixed by `M-x', for example
+`M-x function-name' or are quoted and prefixed like `M-x
+function-name'.
+
+Function names are detected, as well, when appearing behind the
+following forms, which occur - for example - in the Elisp manual:
+
+ -- Special Form: function-name
+ -- Command: ...
+ -- Function: ...
+ -- Macro: ...
+
+The linking is similar to mechanisms from lisp/help.el."
+  (interactive "b")
+  (when (info-check-docu-p)
+    (with-current-buffer (or buffer (current-buffer))
+      (save-excursion
+        (goto-char (point-min))
+        (with-silent-modifications
+          (let ((case-fold-search t)
+                (inhibit-read-only t))
+            (with-syntax-table emacs-lisp-mode-syntax-table
+              ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+              ;; The fofllowing is for finding "quoted symbols"
+              (save-excursion
+                (while (re-search-forward info-symbol-regexp nil t)
+                  ;; sym-group is the regexp group for the symbol name
+                  (let* ((sym-group (+ 3 (length info-symbol-context)))
+                         (data (match-string sym-group))
+                         (sym (intern-soft data)))
+                    (if sym
+                        (cond
+                         ((info-check-type 'variable)
+                          (and (or (boundp sym)
+                                   (get sym 'variable-documentation))
+                               (info-button sym-group 'info-variable sym)))
+                         ((info-check-type 'function)
+                          (and (fboundp sym)
+                               (info-button sym-group 'info-function sym)))
+                         ((info-check-type 'face)
+                          (and (facep sym)
+                               (info-button sym-group 'info-face sym)))
+                         ((info-check-type 'ignore))
+                         ((info-check-type 'definition)
+                          (info-button sym-group 'info-function-def sym))
+                         ;; for symbols
+                         ((cl-some (lambda (x) (funcall (nth 1 x) sym))
+                                   describe-symbol-backends)
+                          (info-button sym-group 'info-symbol sym)))))))
+              ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+              ;; See e.g.: (info "(elisp) Eval")
+              ;; Elisp manual      -- Special Form:
+              ;;                   -- Command:
+              ;;                   -- Function: function-name function
+              ;;                   -- Macro:
+              (save-excursion
+                (while (re-search-forward
+                        "-- \\(Special Form:\\|Command:\\|Function:\\|Macro:\\) "
+                        nil t)
+                  (looking-at "\\(\\sw\\|\\s_\\)+")
+                  (let ((sym (intern-soft (match-string 0))))
+                    (if (fboundp sym)
+                        (info-button 0 'info-function sym)))))
+              ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+              ;;              -- User Option:
+              ;;              -- Variable: variable-name
+              (save-excursion
+                (while (re-search-forward
+                        "-- \\(User Option:\\|Variable:\\) "
+                        nil t)
+                  (looking-at "\\(\\sw\\|\\s_\\)+")
+                  (let ((sym (intern-soft (match-string 0))))
+                    (if (boundp sym)
+                        (info-button 0 'info-variable sym)))))
+              ;; M-x prefixed functions
+              (save-excursion
+                (while (re-search-forward
+                        ;; Assume command name is only word and symbol
+                        ;; characters to get things like `use M-x foo->bar'.
+                        ;; Command required to end with word constituent
+                        ;; to avoid `.' at end of a sentence.
+                        ;; "\\<M-x\\s-+\\(\\sw\\(\\sw\\|\\s_\\)*\\sw\\)" nil t)
+                        ;; include M-x and quotes
+                        "['`‘]?M-x\\s-*\n?\\(\\sw\\(\\sw\\|\\s_\\)*\\sw\\)['’]?" nil t)
+                  (let ((sym (intern-soft (match-string 1))))
+                    (if (fboundp sym)
+                        (info-button 1 'info-function sym))))))))))))
+
 (provide 'info)
 
 ;;; info.el ends here
-- 
2.34.1


[-- Attachment #4: Type: text/plain, Size: 57 bytes --]



-- 
Best wishes
H. Dieter Wilhelm
Zwingenberg, Germany

^ permalink raw reply related	[flat|nested] 58+ messages in thread

* bug#60587: Patch for adding links to symbols' help documentation
  2023-02-05  0:48                     ` H. Dieter Wilhelm
@ 2023-02-05  3:54                       ` Stefan Monnier via Bug reports for GNU Emacs, the Swiss army knife of text editors
  2023-02-05 13:54                         ` H. Dieter Wilhelm
  2023-02-12 11:04                         ` H. Dieter Wilhelm
  0 siblings, 2 replies; 58+ messages in thread
From: Stefan Monnier via Bug reports for GNU Emacs, the Swiss army knife of text editors @ 2023-02-05  3:54 UTC (permalink / raw)
  To: H. Dieter Wilhelm; +Cc: Eli Zaretskii, 60587@debbugs.gnu.org, Drew Adams

> +(define-minor-mode info-button-mode
> +  "The mode creates buttons on symbols linking to their help documentation.
> +
> +"
> +  :init-value nil
> +  :lighter " B"
> +  :group 'info
> +  :version "30.1"

Since you have not specified `:global t`, this is a buffer-local minor
mode, i.e. each buffer will have its own value of the `info-button-mode` boolean.

[ BTW, whether the links look like buttons or not seems rather
  incidental, so I think the mode's name should talk about something more
  precise than "button".
  Maybe something like `info-links-to-help-mode`?  ]

> +  (if (string= major-mode "Info-mode")

`major-mode` contains a symbol, so better do (eq major-mode 'Info-mode).
This said, I don't know why you have that test.  Any reason you're
worried about this being called from another buffer?

> +      (if info-button-mode
> +          (progn
> +            (add-hook 'Info-selection-hook 'info-make-button)
> +            (info-make-button))               ;for the current buffer
> +        (remove-hook 'Info-selection-hook 'info-make-button)

Here, you install/remove the `info-make-button` function to the global
part of the `Info-selection-hook` so it will affect all Info buffers
rather than just the current one.

I don't know if this minor mode should be global or buffer-local, but
please try and make it consistent: if it's buffer-local, then it should
only affect the current buffer.

BTW, the name `info-make-button` suggests it creates a single button
(and provides no info about what kind of button this might be).

> +        (setq inhibit-read-only t)
> +        (remove-list-of-text-properties (point-min) (point-max)
> +                                        '(button category info-args))
> +        (set-buffer-modified-p nil))

I think you wanted to use `with-silent-modifications` here :-)


        Stefan






^ permalink raw reply	[flat|nested] 58+ messages in thread

* bug#60587: Patch for adding links to symbols' help documentation
  2023-02-05  3:54                       ` Stefan Monnier via Bug reports for GNU Emacs, the Swiss army knife of text editors
@ 2023-02-05 13:54                         ` H. Dieter Wilhelm
  2023-02-06 21:04                           ` H. Dieter Wilhelm
  2023-02-12 11:04                         ` H. Dieter Wilhelm
  1 sibling, 1 reply; 58+ messages in thread
From: H. Dieter Wilhelm @ 2023-02-05 13:54 UTC (permalink / raw)
  To: Stefan Monnier; +Cc: Eli Zaretskii, 60587@debbugs.gnu.org, Drew Adams

Stefan Monnier <monnier@iro.umontreal.ca> writes:

>> +(define-minor-mode info-button-mode
>> +  "The mode creates buttons on symbols linking to their help documentation.
>> +..."
>> +  :init-value nil
>> +  :lighter " B"
>> +  :group 'info
>> +  :version "30.1"
>
> Since you have not specified `:global t`, this is a buffer-local minor
> mode, i.e. each buffer will have its own value of the `info-button-mode` boolean.
>
> [ BTW, whether the links look like buttons or not seems rather
>   incidental, so I think the mode's name should talk about something more
>   precise than "button".
>   Maybe something like `info-links-to-help-mode`?  ]

Indeed, I've changed already the non-descriptive names, thanks.

>> +  (if (string= major-mode "Info-mode")
>
> `major-mode` contains a symbol, so better do (eq major-mode 'Info-mode).

I see, I confused the symbol with its name.  (Strange then that my
version worked, anyway?)

> This said, I don't know why you have that test.  Any reason you're
> worried about this being called from another buffer?

Because this info-links-to-help-mode is useless in all buffers, except..

.. Well, I had blinkers on.  Indeed, such a mode might be helpful for
buffers except *info*! Thank you.

Is it worthwhile to generalise the functionality (maybe later), that is
the question?

>> +      (if info-button-mode
>> +          (progn
>> +            (add-hook 'Info-selection-hook 'info-make-button)
>> +            (info-make-button))               ;for the current buffer
>> +        (remove-hook 'Info-selection-hook 'info-make-button)
>
> Here, you install/remove the `info-make-button` function to the global
> part of the `Info-selection-hook` so it will affect all Info buffers
> rather than just the current one.

I guess a user who doesn't like help linking won't appreciate it in all
info buffers, cloned or not.

> I don't know if this minor mode should be global or buffer-local, but
> please try and make it consistent: if it's buffer-local, then it should
> only affect the current buffer.

Please let me rethink the approach in the light of above discussion.

> BTW, the name `info-make-button` suggests it creates a single button
> (and provides no info about what kind of button this might be).

Yes, it's poor, I improved the name.

>> +        (setq inhibit-read-only t)
>> +        (remove-list-of-text-properties (point-min) (point-max)
>> +                                        '(button category info-args))
>> +        (set-buffer-modified-p nil))
>
> I think you wanted to use `with-silent-modifications` here :-)

I think so, thank you.  😊

  Dieter

-- 
Best wishes
H. Dieter Wilhelm
Zwingenberg, Germany





^ permalink raw reply	[flat|nested] 58+ messages in thread

* bug#60587: Patch for adding links to symbols' help documentation
  2023-02-05 13:54                         ` H. Dieter Wilhelm
@ 2023-02-06 21:04                           ` H. Dieter Wilhelm
  0 siblings, 0 replies; 58+ messages in thread
From: H. Dieter Wilhelm @ 2023-02-06 21:04 UTC (permalink / raw)
  To: Stefan Monnier
  Cc: Eli Zaretskii, 60587@debbugs.gnu.org, Drew Adams, Juri Linkov

"H. Dieter Wilhelm" <dieter@duenenhof-wilhelm.de> writes:

> Stefan Monnier <monnier@iro.umontreal.ca> writes:
>
>> This said, I don't know why you have that test.  Any reason you're
>> worried about this being called from another buffer?
>
> Because this info-links-to-help-mode is useless in all buffers, except..
>
> .. Well, I had blinkers on.  Indeed, such a mode might be helpful for
> buffers except *info*! Thank you.

By chance, I just found a nice example for other buffer modes
(view-emacs-news); and which is already implemented for Emacs-29! 😅

> Is it worthwhile to generalise the functionality (maybe later), that is
> the question?

I'll have a look how it is implemented and what to learn from it..

Thanks again

       Dieter
-- 
Best wishes
H. Dieter Wilhelm
Zwingenberg, Germany





^ permalink raw reply	[flat|nested] 58+ messages in thread

* bug#60587: Patch for adding links to symbols' help documentation
  2023-02-05  3:54                       ` Stefan Monnier via Bug reports for GNU Emacs, the Swiss army knife of text editors
  2023-02-05 13:54                         ` H. Dieter Wilhelm
@ 2023-02-12 11:04                         ` H. Dieter Wilhelm
  2023-02-14 20:56                           ` Stefan Monnier via Bug reports for GNU Emacs, the Swiss army knife of text editors
  2023-02-15  5:17                           ` Richard Stallman
  1 sibling, 2 replies; 58+ messages in thread
From: H. Dieter Wilhelm @ 2023-02-12 11:04 UTC (permalink / raw)
  To: Stefan Monnier
  Cc: Juri Linkov, Eli Zaretskii, 60587@debbugs.gnu.org, Drew Adams

[-- Attachment #1: Type: text/plain, Size: 878 bytes --]

Stefan Monnier <monnier@iro.umontreal.ca> writes:

>> +  (if (string= major-mode "Info-mode")
>
> `major-mode` contains a symbol, so better do (eq major-mode 'Info-mode).
> This said, I don't know why you have that test.  Any reason you're
> worried about this being called from another buffer?

No, not any longer 😊.  In the meantime I mentioned the example of
'emacs-news-mode' also linking quoted symbols (and Info references) to
their documentation.  So 'info-link-to-help-mode' is now a local
minor-mode which should work for any buffer.  (I understood that it's
supposed to be the default for all *info* buffers.)

If all agree on this direction I'll adjust the Info documentation
accordingly..

But then, doesn't it makes sense to develop such a universal mode
independent of info.el, e.g. like a 'bug-reference-mode'?

Thanks for your opinions


[-- Attachment #2: 0001-Info-providing-buttons-on-quoted-symbols-bug-60587.patch --]
[-- Type: text/x-diff, Size: 20870 bytes --]

From 7d8e1ce37b35a782430b985b0f7b54aa24377388 Mon Sep 17 00:00:00 2001
From: Dieter Wilhelm <dieter@duenenhof-wilhelm.de>
Date: Wed, 25 Jan 2023 22:00:57 +0100
Subject: [PATCH] Info providing buttons on quoted symbols (bug#60587)

*lisp/info.el
---
 lisp/info.el | 450 +++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 450 insertions(+)

diff --git a/lisp/info.el b/lisp/info.el
index 035dff66e75..a7fa11e6a5c 100644
--- a/lisp/info.el
+++ b/lisp/info.el
@@ -5510,6 +5510,456 @@ info--manual-names
 					     Info-directory-list
 					     (mapcar #'car Info-suffix-list))))))))
 
+\f
+;;; Commentary:
+
+;; All code below provides buttons of symbols (functions, variables,
+;; and faces) within Emacs' Info viewer linking to their builtin help
+;; documentation.  This linking is done when symbol names in texinfo
+;; documentation (like the Emacs- and Elisp manual) are:
+
+;; 1. Quoted symbol names like `symbol-name'.
+
+;; 2. Function names which are prefixed by M-x, for example M-x
+;; function-name or are quoted and prefixed, like `M-x function-name'.
+
+;; 3. Function names appearing behind the following forms, which
+;; occur, for example, in the Elisp manual: (info "(elisp) Eval")
+
+;;   -- Special Form: function-name
+;;   -- Command: ...
+;;   -- Function: ...
+;;   -- Macro: ...
+
+;; 4. And variables names behind the following text:
+
+;;   -- User Option: variable-name
+;;   -- Variable: ...
+
+;; In any case all symbol names must be known to Emacs, which means it
+;; is either a built-in, or its Lisp package is loaded for the current
+;; Emacs session, or the symbol is auto-loaded.
+
+;; You can follow the additional links with the usual Info
+;; keybindings.  The customisation variable
+;; `mouse-1-click-follows-link' is influencing the clicking behavior
+;; (and tooltips) of the links, the variable's default is 450 (milli
+;; seconds) setting it to nil means only clicking with mouse-2 is
+;; following the link (hint: Drew Adams).
+
+;; The link color of symbols - referencing their builtin documentation
+;; - is distinct from links which are referencing further Info
+;; documentation.
+
+;; Below code is checking if Info documents are relevant Elisp and
+;; Emacs related files to avoid false positives.  Please see the
+;; customization variable `info-none-emacs-or-elisp-documents'.
+
+;; The code uses mostly mechanisms from Emacs' lisp/help-mode.el file.
+
+\f
+;;; Code:
+
+(require 'button)
+(require 'cl-lib)
+(require 'help-mode)
+(require 'cl-seq)
+(require 'subr-x)
+
+;;;###autoload
+(define-minor-mode info-links-to-help-mode
+  "The mode creates buttons on symbols linking to their documentation string.
+It shows their documentation in a *Help* buffers (in another
+window) when typing <RET> or clicking `mouse-2' on the buttons.
+These can be followed, as the regular Info manual references,
+with \\[Info-next-reference] and \\[Info-prev-reference].
+
+For details about which symbols are considered and the linking
+process itself please see the function `info-make-links-to-help'."
+  :init-value nil
+  :lighter " Hlp"
+  :group 'info
+  :version "30.1"
+  ;;(if (eq major-mode 'Info-mode)
+  (if info-links-to-help-mode
+      (progn
+        (if (eq major-mode 'Info-mode)
+            ;; we need this under Info-mode because of the narrowed
+            ;; Info file
+            (add-hook 'Info-selection-hook 'info-make-links-to-help))
+        (info-make-links-to-help))      ;for the current buffer
+    (with-silent-modifications
+      (if (eq major-mode 'Info-mode)
+          (remove-hook 'Info-selection-hook 'info-make-links-to-help))
+      ;; TODO: for Info mode we need to remove buttons from the whole
+      ;; (unnarrowed) file! (Actually for all buffers under "Hlp" mode.. :-/)
+      (remove-list-of-text-properties (point-min) (point-max)
+                                      '(button category info-args))))
+  ;;(setq info-links-to-help-mode nil)
+  ;;)
+  )
+;; No defcustom for variable i-l-t-h-m since it activates it for ALL
+;; buffers when setting i-l-t-h-m to none-nil
+
+;; Activate the mode for all Info buffers
+(add-hook 'Info-mode-hook 'info-links-to-help-mode)
+
+(defvar info-emacs-info-dir-content nil
+  "List of file names in Emacs' info directories.
+It is used to check if the current info file `Info-current-file'
+belongs to the Emacs and Elisp context.  This variable will be
+initialised when opening the first info file.")
+
+(defcustom info-none-emacs-or-elisp-documents
+  '("aarm2012"   ; Ada manual from package "ada-ref-man", 2023 on Elpa
+    "aarm2020"   ; Ada manual from package "ada-ref-man", 2023 on Elpa
+    "arm2012"    ; Ada manual from package "ada-ref-man", 2023 on Elpa
+    "arm2020"    ; Ada manual from package "ada-ref-man", 2023 on Elpa
+    "sicp"       ; Structure and Interpretation of Computer Programs,
+                                        ; package "sicp" 2023 on Melpa archive
+    )
+  "List of documentation which is not related to GNU Emacs or Elisp.
+As well as documents which should not be searched for linking to
+help documentation, for more details please see
+`info-check-docu-p'.  The list must contain only the base name of
+info files, e.g. without the file extension \".info\"."
+  :type '(repeat string)
+  :version "30.1"
+  :group 'info)
+
+(defun info-check-docu-p ()
+  "Check if the current info file is relevant to Emacs or Elisp.
+That means `Info-current-file' is either found in Emacs' info/
+directory or in `package-user-dir' and is not included in the
+`info-none-emacs-or-elisp-documents' list."
+  ;; When initialising Info and `Info-mode-hook' is running there is
+  ;; not yet `Info-current-file' initialised
+  (when Info-current-file
+    (unless info-emacs-info-dir-content
+      (info-compile-emacs-info-dir-content))
+    (let* ((ifile Info-current-file) ;I-c-f doesn't yield file suffices!
+           (ifi (file-name-nondirectory ifile))
+           ;; Verify that checking pdir is redundant because Package
+           ;; adds info package folders to Info-directory-list
+           (pdir (when (boundp 'package-user-dir)
+                   (expand-file-name
+                    package-user-dir)))
+           (ifiles info-emacs-info-dir-content)
+           (ndocu info-none-emacs-or-elisp-documents)
+           (sufs (mapcar 'car Info-suffix-list))
+           (vars (mapcar #'(lambda (x)(concat ifi x)) sufs))
+           (emacsy (and ifile
+                        (or (cl-intersection vars ifiles :test #'string=)
+                            (when pdir (string-match pdir ifile)))
+                        (not (assoc-string ifi ndocu)))))
+      (if emacsy
+          t))))
+
+(defvar describe-symbol-backends)      ;from help-mode.el
+(defvar help-xref-following)           ;dito
+
+(defvar-keymap info-button-map
+  :doc "Keymap used by buttons in Info buffers."
+  "RET" #'push-button
+  "<mouse-2>" #'push-button
+  "<follow-link>" 'mouse-face
+  "<mode-line> <mouse-2>" #'push-button
+  "<header-line> <mouse-2>" #'push-button)
+
+;;
+;; Button types
+;;
+
+;; Below parent button type `info' inherits Info's quoted symbol face
+;; `Info-quoted'.  Otherwise the buttons would inherit from
+;; button.el's `link' face which looks identical to Info's links.  But
+;; I think it is helpful to distinguish between button link and cross
+;; reference types because they react differently.
+(define-button-type 'info
+  'link t
+  'follow-link t
+  'face 'Info-quoted
+  'keymap info-button-map
+  'action #'info-button-action)
+
+(define-button-type 'info-function
+  :supertype 'info
+  'info-function 'describe-function
+  'help-echo (purecopy "mouse-2, RET: describe this function"))
+
+(define-button-type 'info-variable
+  :supertype 'info
+  'info-function 'describe-variable
+  'help-echo (purecopy "mouse-2, RET: describe this variable"))
+
+(define-button-type 'info-face
+  :supertype 'info
+  'info-function 'describe-face
+  'help-echo (purecopy "mouse-2, RET: describe this face"))
+
+(define-button-type 'info-symbol
+  :supertype 'info
+  'info-function #'describe-symbol
+  'help-echo (purecopy "mouse-2, RET: describe this symbol"))
+
+(define-button-type 'info-function-def
+  :supertype 'info
+  'info-function (lambda (fun &optional file type)
+                   (or file
+                       (setq file (find-lisp-object-file-name fun type)))
+                   (if (not file)
+                       (message "Unable to find defining file")
+                     (require 'find-func)
+                     (when (eq file 'C-source)
+                       (setq file
+                             (help-C-file-name (indirect-function fun) 'fun)))
+                     ;; Don't use find-function-noselect because it follows
+                     ;; aliases (which fails for built-in functions).
+                     (let ((location
+                            (find-function-search-for-symbol fun type file)))
+                       (pop-to-buffer (car location))
+                       (run-hooks 'find-function-after-hook)
+                       (if (cdr location)
+                           (goto-char (cdr location))
+                         (message "Unable to find location in file")))))
+  'help-echo (purecopy "mouse-2, RET: find function's definition"))
+
+(defun info-compile-emacs-info-dir-content ()
+  "Build a list of file names from Emacs' info directories.
+This function fills `info-emacs-info-dir-content' with files from
+`Info-directory-list'."
+  (setq info-emacs-info-dir-content
+        (mapcar 'file-name-nondirectory
+                (directory-files
+                 (car
+                  ;; search for the main Emacs' info/ directory, when this
+                  ;; function is called Info-directory-list is already
+                  ;; initialised
+                  (cl-member "[^.]emacs" Info-directory-list :test
+                             'string-match-p))
+                 ;; don't list "." and ".."
+                 t  "[^.]$"))))
+
+(defun info-button-action (button)
+  "Call BUTTON's help function."
+  (info-do-xref nil
+                (button-get button 'info-function)
+                (button-get button 'info-args)))
+
+(defun info-do-xref (_pos function args)
+  "Call the help cross-reference function FUNCTION with args ARGS.
+Things are set up properly so that the resulting `help-buffer' has
+a proper [back] button."
+  ;; There is a reference at point.  Follow it.
+  (let ((help-xref-following nil))
+    (apply
+     function (if (eq function 'info)
+                  (append args (list (generate-new-buffer-name "*info*")))args))))
+
+(defun info-button (match-number type &rest args)
+  "Make a hyperlink for cross-reference text previously matched.
+MATCH-NUMBER is the subexpression of interest in the last matched
+regexp.  TYPE is the type of button to use.  Any remaining
+arguments are passed to the button's info-function when it is
+invoked.  See `info-make-links-to-help'.  Don't forget ARGS."
+  ;; Don't munge properties we've added, especially in some instances.
+  (unless (button-at (match-beginning match-number))
+    (make-text-button (match-beginning match-number)
+                      (match-end match-number)
+                      'type type 'info-args args)))
+
+(defvar info-symbol-context
+  '((variable . "variable\\|option")
+    (function . "function\\|command\\|call")
+    (face . "face")
+    ;; ignore symbols following this context type
+    (ignore . "symbol\\|program\\|property")
+    ;; function definitions in files
+    (definition . "source \\(?:code \\)?\\(?:of\\|for\\)"))
+  "This list helps to distinguish symbol types.
+Words in info documentation preceding a (quoted) symbol are used
+to distinguish variables, functions, faces and symbols.  The
+context information can also be used to ignore symbols because
+there is no help documentation for them.  The strings of the the
+list are becoming part of `info-symbol-regexp'.")
+
+(defvar info-symbol-regexp
+  ;; better use purecopy?
+  (concat
+   "\\("                                ; Context start
+   "\\<\\("                             ; Contex type definition
+   (string-remove-suffix
+    "\\|"
+    (mapconcat
+     (lambda (x) (concat "\\(" (cdr x) "\\)\\|"))
+     info-symbol-context ""))
+   "\\)"          ; Context type definition end
+   "[ \t\n]+"     ; Separators to quoted symbols
+   "\\)?"         ; End of context
+   ;; quoted symbol
+   "['`‘]"	  ; opening quotes
+   ;; Note: Symbol starting with word-syntax character:
+   "\\(\\sw\\(\\sw\\|\\s_\\)+\\|`\\)" ; The symbol itself
+   "['’]"                             ; End quotes
+   )
+  "The regular expression for matching symbols to their help documentation.
+It is comprised of the symbol's context and the (quoted) symbol
+name.  The various groups of context regular expressions are
+matched in `info-make-links-to-help' to distinct info buttons.")
+
+(defun info-check-type( type)
+  "Check if TYPE corresponds to the current search result.
+The function is used in `info-make-links-to-help'."
+  (let* ((isc info-symbol-context)
+	 (n 3)                          ;embedded within 2 groups
+         (l (+ 3 (length isc))))
+    (while (and (not (eq type (caar isc) ) ) (< n l) )
+      (setq n (1+ n))
+      (setq isc (cdr isc)))
+    (match-string n)))
+
+\f
+;;;###autoload
+(defun info-make-links-to-help (&optional buffer)
+  "Parse and hyperlink quoted symbols in the given BUFFER.
+BUFFER defaults to the current buffer if omitted or nil.  Find
+symbols and their context in an Info buffer and activate buttons
+for linking to their documentation string with `info-button'.
+
+Symbols have the canonical (quoted) form `symbol-name' and the
+type of reference may be disambiguated by the preceding word(s)
+as compiled in `info-symbol-regexp'.  For example: Symbol names
+are receiving distinct variable buttons when preceeded by the
+words \"variable\" or \"option\".
+
+Variables are also detected when their names follow below forms:
+
+ -- User Option: variable-name
+ -- Variable: ...
+
+Function names are detected when prefixed by `M-x', for example
+`M-x function-name' or are quoted and prefixed like `M-x
+function-name'.
+
+Function names are detected, as well, when appearing behind the
+following forms, which occur - for example - in the Elisp manual:
+
+ -- Special Form: function-name
+ -- Command: ...
+ -- Function: ...
+ -- Macro: ...
+
+The linking is similar to mechanisms from lisp/help.el."
+  (interactive "b")                     ;asking for buffer name..
+  (if (eq major-mode 'Info-mode)
+      (when (info-check-docu-p)
+        (with-current-buffer (or buffer (current-buffer))
+          (save-excursion
+            (goto-char (point-min))
+            (with-silent-modifications
+              (let ((case-fold-search t)
+                    (inhibit-read-only t))
+                (with-syntax-table emacs-lisp-mode-syntax-table
+                  ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+                  ;; The following is for finding "quoted symbols"
+                  (save-excursion
+                    (while (re-search-forward info-symbol-regexp nil t)
+                      ;; sym-group is the regexp group for the symbol name
+                      (let* ((sym-group (+ 3 (length info-symbol-context)))
+                             (data (match-string sym-group))
+                             (sym (intern-soft data)))
+                        (if sym
+                            (cond
+                             ((info-check-type 'variable)
+                              (and (or (boundp sym)
+                                       (get sym 'variable-documentation))
+                                   (info-button sym-group 'info-variable sym)))
+                             ((info-check-type 'function)
+                              (and (fboundp sym)
+                                   (info-button sym-group 'info-function sym)))
+                             ((info-check-type 'face)
+                              (and (facep sym)
+                                   (info-button sym-group 'info-face sym)))
+                             ((info-check-type 'ignore))
+                             ((info-check-type 'definition)
+                              (info-button sym-group 'info-function-def sym))
+                             ;; for symbols
+                             ((cl-some (lambda (x) (funcall (nth 1 x) sym))
+                                       describe-symbol-backends)
+                              (info-button sym-group 'info-symbol sym)))))))
+                  ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+                  ;; See e.g.: (info "(elisp) Eval")
+                  ;; Elisp manual      -- Special Form:
+                  ;;                   -- Command:
+                  ;;                   -- Function: function-name function
+                  ;;                   -- Macro:
+                  (save-excursion
+                    (while (re-search-forward
+                            "-- \\(Special Form:\\|Command:\\|Function:\\|Macro:\\) "
+                            nil t)
+                      (looking-at "\\(\\sw\\|\\s_\\)+")
+                      (let ((sym (intern-soft (match-string 0))))
+                        (if (fboundp sym)
+                            (info-button 0 'info-function sym)))))
+                  ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+                  ;;              -- User Option:
+                  ;;              -- Variable: variable-name
+                  (save-excursion
+                    (while (re-search-forward
+                            "-- \\(User Option:\\|Variable:\\) "
+                            nil t)
+                      (looking-at "\\(\\sw\\|\\s_\\)+")
+                      (let ((sym (intern-soft (match-string 0))))
+                        (if (boundp sym)
+                            (info-button 0 'info-variable sym)))))
+                  ;; M-x prefixed functions
+                  (save-excursion
+                    (while (re-search-forward
+                            ;; Assume command name is only word and symbol
+                            ;; characters to get things like `use M-x foo->bar'.
+                            ;; Command required to end with word constituent
+                            ;; to avoid `.' at end of a sentence.
+                            ;; "\\<M-x\\s-+\\(\\sw\\(\\sw\\|\\s_\\)*\\sw\\)" nil t)
+                            ;; include M-x and quotes
+                            "['`‘]?M-x\\s-*\n?\\(\\sw\\(\\sw\\|\\s_\\)*\\sw\\)['’]?" nil t)
+                      (let ((sym (intern-soft (match-string 1))))
+                        (if (fboundp sym)
+                            (info-button 1 'info-function sym)))))))))))
+    ;; other, non-Info buffers
+    (info--buttonize)
+    ))
+
+;; stolen from emacs-news-mode.el
+(defun info--buttonize ()
+  "Make manual and symbol references into buttons."
+  (save-excursion
+    (with-silent-modifications
+      (let ((inhibit-read-only t))
+        ;; Do functions and variables.
+        (goto-char (point-min))
+        (search-forward "\f" nil t)
+        ;; symbol quoting styles: '' and `' (grave accent and
+        ;; apostrophe, pre Emacs-25)
+        (while (re-search-forward "['`]\\([^-][^ \t\n]+\\)'" nil t)
+          ;; Filter out references to key sequences.
+          (let ((string (match-string 1)))
+            (when-let ((symbol (intern-soft string)))
+              (when (or (boundp symbol)
+                        (fboundp symbol))
+                (buttonize-region (match-beginning 1) (match-end 1)
+                                  (lambda (symbol)
+                                    (describe-symbol symbol))
+                                  symbol)))))
+        ;; Do manual references '"(...) ..."'.
+        (goto-char (point-min))
+        (search-forward "\f" nil t)
+        (while (re-search-forward "\"\\(([a-z0-9-]+)[ \n][^\"]\\{1,80\\}\\)\""
+                                  nil t)
+          (buttonize-region (match-beginning 1) (match-end 1)
+                            (lambda (node) (info node))
+                            (match-string 1)))))))
+
+
 (provide 'info)
 
 ;;; info.el ends here
-- 
2.34.1


[-- Attachment #3: Type: text/plain, Size: 70 bytes --]



-- 
   Dieter

Best wishes
H. Dieter Wilhelm
Zwingenberg, Germany
 

^ permalink raw reply related	[flat|nested] 58+ messages in thread

* bug#60587: Patch for adding links to symbols' help documentation
  2023-02-12 11:04                         ` H. Dieter Wilhelm
@ 2023-02-14 20:56                           ` Stefan Monnier via Bug reports for GNU Emacs, the Swiss army knife of text editors
  2023-02-15 22:18                             ` H. Dieter Wilhelm
  2023-02-15  5:17                           ` Richard Stallman
  1 sibling, 1 reply; 58+ messages in thread
From: Stefan Monnier via Bug reports for GNU Emacs, the Swiss army knife of text editors @ 2023-02-14 20:56 UTC (permalink / raw)
  To: H. Dieter Wilhelm
  Cc: Juri Linkov, Eli Zaretskii, 60587@debbugs.gnu.org, Drew Adams

> +(define-minor-mode info-links-to-help-mode
> +  "The mode creates buttons on symbols linking to their documentation string.
> +It shows their documentation in a *Help* buffers (in another
> +window) when typing <RET> or clicking `mouse-2' on the buttons.
> +These can be followed, as the regular Info manual references,
> +with \\[Info-next-reference] and \\[Info-prev-reference].
> +
> +For details about which symbols are considered and the linking
> +process itself please see the function `info-make-links-to-help'."
> +  :init-value nil
> +  :lighter " Hlp"
> +  :group 'info
> +  :version "30.1"
> +  ;;(if (eq major-mode 'Info-mode)
> +  (if info-links-to-help-mode
> +      (progn
> +        (if (eq major-mode 'Info-mode)
> +            ;; we need this under Info-mode because of the narrowed
> +            ;; Info file
> +            (add-hook 'Info-selection-hook 'info-make-links-to-help))
> +        (info-make-links-to-help))      ;for the current buffer

The above `define-minor-mode` still defines a buffer-local minor mode
whereas the above `add-hook` is still global and hence affects all buffers.
This is a recipe for inconsistent behavior.

> +;; Activate the mode for all Info buffers
> +(add-hook 'Info-mode-hook 'info-links-to-help-mode)

Better add a call to `info-links-to-help-mode` directly inside
`Info-mode`.


        Stefan






^ permalink raw reply	[flat|nested] 58+ messages in thread

* bug#60587: Patch for adding links to symbols' help documentation
  2023-02-12 11:04                         ` H. Dieter Wilhelm
  2023-02-14 20:56                           ` Stefan Monnier via Bug reports for GNU Emacs, the Swiss army knife of text editors
@ 2023-02-15  5:17                           ` Richard Stallman
  2023-02-15  9:53                             ` Gregory Heytings
  1 sibling, 1 reply; 58+ messages in thread
From: Richard Stallman @ 2023-02-15  5:17 UTC (permalink / raw)
  To: H. Dieter Wilhelm; +Cc: juri, eliz, 60587, monnier, drew.adams

[[[ To any NSA and FBI agents reading my email: please consider    ]]]
[[[ whether defending the US Constitution against all enemies,     ]]]
[[[ foreign or domestic, requires you to follow Snowden's example. ]]]

  > No, not any longer 😊.

Can someone tell me an easy way to make that particular diamond character
display as the ASCII sequence `;-)'?

-- 
Dr Richard Stallman (https://stallman.org)
Chief GNUisance of the GNU Project (https://gnu.org)
Founder, Free Software Foundation (https://fsf.org)
Internet Hall-of-Famer (https://internethalloffame.org)







^ permalink raw reply	[flat|nested] 58+ messages in thread

* bug#60587: Patch for adding links to symbols' help documentation
  2023-02-15  5:17                           ` Richard Stallman
@ 2023-02-15  9:53                             ` Gregory Heytings
  2023-02-15 13:42                               ` Gregory Heytings
  0 siblings, 1 reply; 58+ messages in thread
From: Gregory Heytings @ 2023-02-15  9:53 UTC (permalink / raw)
  To: Richard Stallman
  Cc: H. Dieter Wilhelm, 60587, juri, monnier, eliz, drew.adams

[-- Attachment #1: Type: text/plain, Size: 554 bytes --]


>> No, not any longer 😊.
>
> Can someone tell me an easy way to make that particular diamond 
> character display as the ASCII sequence `;-)'?
>

(defun set-character-display (char repl)
   (let ((c (char-from-name char)))
     (when (and c (stringp repl))
       (aset (or standard-display-table
 		(setq standard-display-table (make-display-table)))
 	    c
 	    (vconcat
 	     (mapcar
 	      (lambda (char) (make-glyph-code char 'homoglyph))
 	      repl))))))

(set-character-display "SMILING FACE WITH SMILING EYES" ":-)")

^ permalink raw reply	[flat|nested] 58+ messages in thread

* bug#60587: Patch for adding links to symbols' help documentation
  2023-02-15  9:53                             ` Gregory Heytings
@ 2023-02-15 13:42                               ` Gregory Heytings
  0 siblings, 0 replies; 58+ messages in thread
From: Gregory Heytings @ 2023-02-15 13:42 UTC (permalink / raw)
  To: Richard Stallman
  Cc: H. Dieter Wilhelm, 60587, juri, monnier, eliz, drew.adams

[-- Attachment #1: Type: text/plain, Size: 967 bytes --]


>>> No, not any longer 😊.
>> 
>> Can someone tell me an easy way to make that particular diamond 
>> character display as the ASCII sequence `;-)'?
>
> (defun set-character-display (char repl)
>  (let ((c (char-from-name char)))
>    (when (and c (stringp repl))
>      (aset (or standard-display-table
> 		(setq standard-display-table (make-display-table)))
> 	    c
> 	    (vconcat
> 	     (mapcar
> 	      (lambda (char) (make-glyph-code char 'homoglyph))
> 	      repl))))))
>
> (set-character-display "SMILING FACE WITH SMILING EYES" ":-)")
>

Or, if you don't want to use the homoglyph face for such replacements:

(defun set-character-display (char repl)
   (let ((c (char-from-name char)))
     (when (and c (stringp repl))
       (aset (or standard-display-table
              (setq standard-display-table (make-display-table)))
          c (vconcat repl)))))

(set-character-display "SMILING FACE WITH SMILING EYES" ":-)")

^ permalink raw reply	[flat|nested] 58+ messages in thread

* bug#60587: Patch for adding links to symbols' help documentation
  2023-02-14 20:56                           ` Stefan Monnier via Bug reports for GNU Emacs, the Swiss army knife of text editors
@ 2023-02-15 22:18                             ` H. Dieter Wilhelm
  2023-02-16  3:08                               ` Stefan Monnier via Bug reports for GNU Emacs, the Swiss army knife of text editors
  0 siblings, 1 reply; 58+ messages in thread
From: H. Dieter Wilhelm @ 2023-02-15 22:18 UTC (permalink / raw)
  To: Stefan Monnier
  Cc: Juri Linkov, Eli Zaretskii, 60587@debbugs.gnu.org, Drew Adams

Stefan Monnier <monnier@iro.umontreal.ca> writes:

>> +(define-minor-mode info-links-to-help-mode
>> +  "The mode creates buttons on symbols linking to their documentation string.
>> +It shows their documentation in a *Help* buffers (in another
>> +window) when typing <RET> or clicking `mouse-2' on the buttons.
>> +These can be followed, as the regular Info manual references,
>> +with \\[Info-next-reference] and \\[Info-prev-reference].
>> +
>> +For details about which symbols are considered and the linking
>> +process itself please see the function `info-make-links-to-help'."
>> +  :init-value nil
>> +  :lighter " Hlp"
>> +  :group 'info
>> +  :version "30.1"
>> +  (if info-links-to-help-mode
>> +      (progn
>> +        (if (eq major-mode 'Info-mode)
>> +            ;; we need this under Info-mode because of the narrowed
>> +            ;; Info file
>> +            (add-hook 'Info-selection-hook 'info-make-links-to-help))
>> +        (info-make-links-to-help))      ;for the current buffer
>
> The above `define-minor-mode` still defines a buffer-local minor mode

I thought a minor mode is necessary when 'info-make-links-to-help' is
supposed to work for arbitrary major modes and buffers besides Info.

> whereas the above `add-hook` is still global and hence affects all
> buffers.

I'm not sure I understand, it affects only Info buffers globally (eq
major-mode 'Info-mode).  Do you think it is better to use a global minor
mode for all Info buffers and a separate buffer local mode for other
buffers (and major modes)?

> This is a recipe for inconsistent behavior.
  
>> +;; Activate the mode for all Info buffers
>> +(add-hook 'Info-mode-hook 'info-links-to-help-mode)
>
> Better add a call to `info-links-to-help-mode` directly inside
> `Info-mode`.

(Please tell me why are you quoting with two grave accents and not with
apostrophes?)

Do you think setting

(defcustom Info-mode-hook '(turn-on-font-lock info-links-to-help-mode)
  "Hook run when activating Info Mode."
  :type 'hook
  :version "29.1")

is a possible alternative to call it into 'Info-mode'?

-- 
Thank you

      Dieter

Best wishes
H. Dieter Wilhelm
Zwingenberg, Germany





^ permalink raw reply	[flat|nested] 58+ messages in thread

* bug#60587: Patch for adding links to symbols' help documentation
  2023-02-15 22:18                             ` H. Dieter Wilhelm
@ 2023-02-16  3:08                               ` Stefan Monnier via Bug reports for GNU Emacs, the Swiss army knife of text editors
  2023-02-20 23:53                                 ` H. Dieter Wilhelm
  0 siblings, 1 reply; 58+ messages in thread
From: Stefan Monnier via Bug reports for GNU Emacs, the Swiss army knife of text editors @ 2023-02-16  3:08 UTC (permalink / raw)
  To: H. Dieter Wilhelm
  Cc: Juri Linkov, Eli Zaretskii, 60587@debbugs.gnu.org, Drew Adams

H. Dieter Wilhelm [2023-02-15 23:18:17] wrote:
> Stefan Monnier <monnier@iro.umontreal.ca> writes:
>>> +(define-minor-mode info-links-to-help-mode
>>> +  "The mode creates buttons on symbols linking to their documentation string.
>>> +It shows their documentation in a *Help* buffers (in another
>>> +window) when typing <RET> or clicking `mouse-2' on the buttons.
>>> +These can be followed, as the regular Info manual references,
>>> +with \\[Info-next-reference] and \\[Info-prev-reference].
>>> +
>>> +For details about which symbols are considered and the linking
>>> +process itself please see the function `info-make-links-to-help'."
>>> +  :init-value nil
>>> +  :lighter " Hlp"
>>> +  :group 'info
>>> +  :version "30.1"
>>> +  (if info-links-to-help-mode
>>> +      (progn
>>> +        (if (eq major-mode 'Info-mode)
>>> +            ;; we need this under Info-mode because of the narrowed
>>> +            ;; Info file
>>> +            (add-hook 'Info-selection-hook 'info-make-links-to-help))
>>> +        (info-make-links-to-help))      ;for the current buffer
>>
>> The above `define-minor-mode` still defines a buffer-local minor mode
>
> I thought a minor mode is necessary when 'info-make-links-to-help' is
> supposed to work for arbitrary major modes and buffers besides Info.

I don't understand your remark.  I'm pointing out that the way you use
`define-minor-mode` above makes it buffer-local (if you want it to be
global, which is probably simpler you need to say `:global t`).

>> whereas the above `add-hook` is still global and hence affects all
>> buffers.
> I'm not sure I understand, it affects only Info buffers globally (eq
> major-mode 'Info-mode).

But it affects all Info-mode buffers whereas the
`info-links-to-help-mode` variable will only be set buffer-locally in
the current-buffer.  So you'll have Info-mode buffers where
`info-make-links-to-help` has been added to `Info-selection-hook` even
though its `info-links-to-help-mode` var is nil and you can have others
with the reverse.

> Do you think it is better to use a global minor mode for all Info
> buffers and a separate buffer local mode for other buffers (and major
> modes)?

If I were you, I'd just use a single global minor mode that affects all
Info-mode buffers (and only Info-mode buffers).  It should be rather rare
for a user to want to enable this in some buffers but not all.

We can easily add another global minor mode (using the same underlying
code) for the NEWS files if we want.

>> Better add a call to `info-links-to-help-mode` directly inside
>> `Info-mode`.
> (Please tell me why are you quoting with two grave accents and not with
> apostrophes?)

I try to follow the Markdown convention.

> Do you think setting
>
> (defcustom Info-mode-hook '(turn-on-font-lock info-links-to-help-mode)
>   "Hook run when activating Info Mode."
>   :type 'hook
>   :version "29.1")
>
> is a possible alternative to call it into 'Info-mode'?

I think I was confused because.  IIUC what you're trying to do is to
default this new minor mode to "enabled".  In that case I think your
code is somewhat OK though you should protect the `add-hook` with a test
for the value of the minor-mode to make sure you only run it when the
mode is enabled (which again only makes sense if the mode is global).


        Stefan






^ permalink raw reply	[flat|nested] 58+ messages in thread

* bug#60587: Patch for adding links to symbols' help documentation
  2023-02-16  3:08                               ` Stefan Monnier via Bug reports for GNU Emacs, the Swiss army knife of text editors
@ 2023-02-20 23:53                                 ` H. Dieter Wilhelm
  2023-02-21  2:12                                   ` Stefan Monnier via Bug reports for GNU Emacs, the Swiss army knife of text editors
  0 siblings, 1 reply; 58+ messages in thread
From: H. Dieter Wilhelm @ 2023-02-20 23:53 UTC (permalink / raw)
  To: Stefan Monnier
  Cc: Juri Linkov, Eli Zaretskii, 60587@debbugs.gnu.org, Drew Adams

Stefan Monnier <monnier@iro.umontreal.ca> writes:
>
> If I were you, I'd just use a single global minor mode that affects all
> Info-mode buffers (and only Info-mode buffers).  It should be rather rare
> for a user to want to enable this in some buffers but not all.

I took a step back and refocusing on Info and only Info.  When rewriting
the mode as global minor mode, it's working, easily, for my tests.

The only thing, which feels strange to me, is that
'info-links-to-help-mode' is now a minor mode for all buffers (and
modes).  Sure, it's only affecting 'Info-mode' but isn't there a way of
making it a "global" minor mode only for Info buffers?  Anyway, I
couldn't find a way to restrict global minor modes to certain major
modes.

Do you think the usage of 'define-globalized-minor-mode' is an
alternative for a global minor mode?  As far as I understand, it is
possible to have a global toggle for local minor modes which
automatically enables them for all buffers (optionally, of certain major
modes).

-- 
Thanks
        Dieter

Best wishes
H. Dieter Wilhelm
Zwingenberg, Germany





^ permalink raw reply	[flat|nested] 58+ messages in thread

* bug#60587: Patch for adding links to symbols' help documentation
  2023-02-20 23:53                                 ` H. Dieter Wilhelm
@ 2023-02-21  2:12                                   ` Stefan Monnier via Bug reports for GNU Emacs, the Swiss army knife of text editors
  2023-03-01 21:45                                     ` H. Dieter Wilhelm
  0 siblings, 1 reply; 58+ messages in thread
From: Stefan Monnier via Bug reports for GNU Emacs, the Swiss army knife of text editors @ 2023-02-21  2:12 UTC (permalink / raw)
  To: H. Dieter Wilhelm
  Cc: Juri Linkov, Eli Zaretskii, 60587@debbugs.gnu.org, Drew Adams

> The only thing, which feels strange to me, is that
> 'info-links-to-help-mode' is now a minor mode for all buffers (and
> modes).  Sure, it's only affecting 'Info-mode' but isn't there a way of
> making it a "global" minor mode only for Info buffers?  Anyway, I
> couldn't find a way to restrict global minor modes to certain major
> modes.

No it's perfectly normal to have a global preference that only affects
the buffers for which it's relevant.  I like my food to be spicy and
that's just as true when I eat as when I don't but it has consequences
only when I do.


        Stefan






^ permalink raw reply	[flat|nested] 58+ messages in thread

* bug#60587: Patch for adding links to symbols' help documentation
  2023-02-21  2:12                                   ` Stefan Monnier via Bug reports for GNU Emacs, the Swiss army knife of text editors
@ 2023-03-01 21:45                                     ` H. Dieter Wilhelm
  2023-03-11  8:32                                       ` Eli Zaretskii
  0 siblings, 1 reply; 58+ messages in thread
From: H. Dieter Wilhelm @ 2023-03-01 21:45 UTC (permalink / raw)
  To: Stefan Monnier
  Cc: Juri Linkov, Eli Zaretskii, 60587@debbugs.gnu.org, Drew Adams

[-- Attachment #1: Type: text/plain, Size: 790 bytes --]

Tags: patch

Stefan Monnier <monnier@iro.umontreal.ca> writes:

>> The only thing, which feels strange to me, is that
>> 'info-links-to-help-mode' is now a minor mode for all buffers (and
>> modes).  Sure, it's only affecting 'Info-mode' but isn't there a way of
>> making it a "global" minor mode only for Info buffers?  Anyway, I
>> couldn't find a way to restrict global minor modes to certain major
>> modes.
>
> No it's perfectly normal to have a global preference that only affects
> the buffers for which it's relevant.  I like my food to be spicy and
> that's just as true when I eat as when I don't but it has consequences
> only when I do.
>

Alright :-)

I've adjusted the code and documentation accordingly and created another
patch.

Thank you for your support.

      Dieter


[-- Attachment #2: 0001-Info-providing-buttons-on-quoted-symbols-bug-60587.patch --]
[-- Type: text/x-diff, Size: 23483 bytes --]

From 96ebac084acf21af46980ea6686dd474e4e8974a Mon Sep 17 00:00:00 2001
From: Dieter Wilhelm <dieter@duenenhof-wilhelm.de>
Date: Wed, 25 Jan 2023 22:00:57 +0100
Subject: [PATCH] Info providing buttons on quoted symbols (bug#60587)

*lisp/info.el

Implement as global minor mode

Adjust NEWS for global minor mode

Explain the usage of Info-next-reference

And improve some other documentation

Adjust emacs.texi to the minor mode name
---
 doc/emacs/help.texi |  15 ++
 etc/NEWS            |  11 ++
 lisp/info.el        | 449 ++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 475 insertions(+)

diff --git a/doc/emacs/help.texi b/doc/emacs/help.texi
index 2513e6be271..777adf9bce5 100644
--- a/doc/emacs/help.texi
+++ b/doc/emacs/help.texi
@@ -653,6 +653,21 @@ Misc Help
 K @var{key}}, described above, enter Info and go straight to the
 documentation of @var{function} or @var{key}.
 
+@vindex info-links-to-help-mode
+  In Info, by default, the global minor mode
+@code{info-links-to-help-mode} makes quoted symbol names into buttons
+which link to the symbols' documentation string when typing @key{RET}
+or clicking the mouse (@pxref{Mouse References}).  For example, the
+quoted name @code{info-other-window} is made into a button which shows
+the function's documentation string in another window, in the
+@file{*Help*} buffer.  Info highlights such quoted symbols (variables,
+functions and face names) by a distinct face and these can be reached,
+as the Info manual references, with @key{TAB} and @kbd{S-Tab}.
+
+  If you want to remove these buttons, you can toggle the mode with
+typing @kbd{M-x info-links-to-help-mode} or deactivating it with
+@code{(info-links-to-help-mode -1)} in Emacs' initialisation file.
+
 @kindex C-h S
 @findex info-lookup-symbol
   When editing a program, if you have an Info version of the manual
diff --git a/etc/NEWS b/etc/NEWS
index 31fb22fc1e2..5a58f27726e 100644
--- a/etc/NEWS
+++ b/etc/NEWS
@@ -201,6 +201,17 @@ This command adds a docstring comment to the current defun.  If a
 comment already exists, point is only moved to the comment.  It is
 bound to 'C-c C-d' in 'go-ts-mode'.
 
+** Info
+
++++
+*** New global minor mode 'info-links-to-help-mode'.
+In Info, by default, the mode provides buttons on quoted symbols
+showing their documentation string in the *Help* buffer when typing
+`RET' or clicking `mouse-2'.  These links are working independently of
+the Info cross references and can be toggled with 'M-x
+info-links-to-help-mode' or disabled with '(info-links-to-help-mode
+-1)'.
+
 \f
 * New Modes and Packages in Emacs 30.1
 
diff --git a/lisp/info.el b/lisp/info.el
index 035dff66e75..540e84f3f0f 100644
--- a/lisp/info.el
+++ b/lisp/info.el
@@ -4503,6 +4503,8 @@ Info-mode
   (setq-local revert-buffer-function #'Info-revert-buffer-function)
   (setq-local font-lock-defaults '(Info-mode-font-lock-keywords t t))
   (Info-set-mode-line)
+  (when info-links-to-help-mode
+    (info-links-to-help-mode))
   (setq-local bookmark-make-record-function #'Info-bookmark-make-record)
   (unless search-default-mode
     (isearch-fold-quotes-mode)))
@@ -5510,6 +5512,453 @@ info--manual-names
 					     Info-directory-list
 					     (mapcar #'car Info-suffix-list))))))))
 
+\f
+;;; Commentary:
+
+;; All code below provides buttons of symbols (functions, variables,
+;; and faces) within Emacs' Info viewer linking to their builtin help
+;; documentation.  This linking is done when symbol names in texinfo
+;; documentation (like the Emacs- and Elisp manual) are:
+
+;; 1. Quoted symbol names like `symbol-name'.
+
+;; 2. Function names which are prefixed by M-x, for example M-x
+;; function-name or are quoted and prefixed, like `M-x function-name'.
+
+;; 3. Function names appearing behind the following forms, which
+;; occur, for example, in the Elisp manual: (info "(elisp) Eval")
+
+;;   -- Special Form: function-name
+;;   -- Command: ...
+;;   -- Function: ...
+;;   -- Macro: ...
+
+;; 4. And variables names behind the following text:
+
+;;   -- User Option: variable-name
+;;   -- Variable: ...
+
+;; In any case all symbol names must be known to Emacs, which means it
+;; is either a built-in, or its Lisp package is loaded for the current
+;; Emacs session, or the symbol is auto-loaded.
+
+;; You can follow the additional links with the usual Info
+;; keybindings.  The customisation variable
+;; `mouse-1-click-follows-link' is influencing the clicking behavior
+;; (and tooltips) of the links, the variable's default is 450 (milli
+;; seconds) setting it to nil means only clicking with mouse-2 is
+;; following the link (hint: Drew Adams).
+
+;; The link color of symbols - referencing their builtin documentation
+;; - is distinct from links which are referencing further Info
+;; documentation.
+
+;; Below code is checking if Info documents are relevant Elisp and
+;; Emacs related files to avoid false positives.  Please see the
+;; customization variable `info-none-emacs-or-elisp-documents'.
+
+;; The code uses mostly mechanisms from Emacs' lisp/help-mode.el file.
+
+\f
+;;; Code:
+
+(require 'button)
+(require 'cl-lib)
+(require 'help-mode)
+(require 'cl-seq)
+(require 'subr-x)
+
+;; Below mode can reuse the functions 'Info-next-reference' and
+;; 'Info-prev-reference' since these functions are (also) finding the
+;; text properties of the buttons which are applied for the linking to
+;; help.
+
+;;;###autoload
+(define-minor-mode info-links-to-help-mode
+  "The mode creates buttons on symbols linking to their documentation string.
+It shows their documentation in the *Help* buffer (in another
+window) when typing <RET> or clicking `mouse-2' on the buttons.
+These can be followed, as the Info manual references, with
+\\[Info-next-reference] and \\[Info-prev-reference].
+
+For details about which symbols are considered and the linking
+process itself please see the function `info-make-links-to-help'."
+  :global t
+  :init-value t
+  :group 'info
+  :version "30.1"
+  (if info-links-to-help-mode
+      (progn
+        (when (eq major-mode 'Info-mode)
+          ;; we need this under Info-mode because of the narrowed
+          ;; Info file
+          (add-hook 'Info-selection-hook 'info-make-links-to-help))
+        (info-make-links-to-help))      ;for the current buffer
+    (with-silent-modifications
+      (when (eq major-mode 'Info-mode)
+        (remove-hook 'Info-selection-hook 'info-make-links-to-help))
+      ;; TODO: for Info mode we need to remove buttons from the whole
+      ;; (unnarrowed) file!  Actually for all buffers under this
+      ;; mode..
+      (remove-list-of-text-properties (point-min) (point-max)
+                                      '(button category info-args)))))
+
+(defvar info-emacs-info-dir-content nil
+  "List of file names in Emacs' info directories.
+It is used to check if the current info file `Info-current-file'
+belongs to the Emacs and Elisp context.  This variable will be
+initialised when opening the first info file.")
+
+(defcustom info-none-emacs-or-elisp-documents
+  '("aarm2012"   ; Ada manual from package "ada-ref-man", 2023 on Elpa
+    "aarm2020"   ; Ada manual from package "ada-ref-man", 2023 on Elpa
+    "arm2012"    ; Ada manual from package "ada-ref-man", 2023 on Elpa
+    "arm2020"    ; Ada manual from package "ada-ref-man", 2023 on Elpa
+    "sicp"       ; Structure and Interpretation of Computer Programs,
+                                        ; package "sicp" 2023 on Melpa archive
+    )
+  "List of documentation which is not related to GNU Emacs or Elisp.
+As well as documents which should not be searched for linking to
+help documentation, for more details please see
+`info-check-docu-p'.  The list must contain only the base name of
+info files, e.g. without the file extension \".info\"."
+  :type '(repeat string)
+  :version "30.1"
+  :group 'info)
+
+(defun info-check-docu-p ()
+  "Check if the current info file is relevant to Emacs or Elisp.
+That means `Info-current-file' is either found in Emacs' info/
+directory or in `package-user-dir' and is not included in the
+`info-none-emacs-or-elisp-documents' list."
+  ;; When initialising Info and `Info-mode-hook' is running there is
+  ;; not yet `Info-current-file' initialised
+  (when Info-current-file
+    (unless info-emacs-info-dir-content
+      (info-compile-emacs-info-dir-content))
+    (let* ((ifile Info-current-file) ;I-c-f doesn't yield file suffices!
+           (ifi (file-name-nondirectory ifile))
+           ;; Verify that checking pdir is redundant because Package
+           ;; adds info package folders to Info-directory-list
+           (pdir (when (boundp 'package-user-dir)
+                   (expand-file-name
+                    package-user-dir)))
+           (ifiles info-emacs-info-dir-content)
+           (ndocu info-none-emacs-or-elisp-documents)
+           (sufs (mapcar 'car Info-suffix-list))
+           (vars (mapcar #'(lambda (x)(concat ifi x)) sufs))
+           (emacsy (and ifile
+                        (or (cl-intersection vars ifiles :test #'string=)
+                            (when pdir (string-match pdir ifile)))
+                        (not (assoc-string ifi ndocu)))))
+      (if emacsy
+          t))))
+
+(defvar describe-symbol-backends)      ;from help-mode.el
+(defvar help-xref-following)           ;dito
+
+(defvar-keymap info-button-map
+  :doc "Keymap used by buttons in Info buffers."
+  "RET" #'push-button
+  "<mouse-2>" #'push-button
+  "<follow-link>" 'mouse-face
+  "<mode-line> <mouse-2>" #'push-button
+  "<header-line> <mouse-2>" #'push-button)
+
+;;
+;; Button types
+;;
+
+;; Below parent button type `info' inherits Info's quoted symbol face
+;; `Info-quoted'.  Otherwise the buttons would inherit from
+;; button.el's `link' face which looks identical to Info's links.  But
+;; I think it is helpful to distinguish between button link and cross
+;; reference types because they react differently.
+(define-button-type 'info
+  'link t
+  'follow-link t
+  'face 'Info-quoted
+  'keymap info-button-map
+  'action #'info-button-action)
+
+(define-button-type 'info-function
+  :supertype 'info
+  'info-function 'describe-function
+  'help-echo (purecopy "mouse-2, RET: describe this function"))
+
+(define-button-type 'info-variable
+  :supertype 'info
+  'info-function 'describe-variable
+  'help-echo (purecopy "mouse-2, RET: describe this variable"))
+
+(define-button-type 'info-face
+  :supertype 'info
+  'info-function 'describe-face
+  'help-echo (purecopy "mouse-2, RET: describe this face"))
+
+(define-button-type 'info-symbol
+  :supertype 'info
+  'info-function #'describe-symbol
+  'help-echo (purecopy "mouse-2, RET: describe this symbol"))
+
+(define-button-type 'info-function-def
+  :supertype 'info
+  'info-function (lambda (fun &optional file type)
+                   (or file
+                       (setq file (find-lisp-object-file-name fun type)))
+                   (if (not file)
+                       (message "Unable to find defining file")
+                     (require 'find-func)
+                     (when (eq file 'C-source)
+                       (setq file
+                             (help-C-file-name (indirect-function fun) 'fun)))
+                     ;; Don't use find-function-noselect because it follows
+                     ;; aliases (which fails for built-in functions).
+                     (let ((location
+                            (find-function-search-for-symbol fun type file)))
+                       (pop-to-buffer (car location))
+                       (run-hooks 'find-function-after-hook)
+                       (if (cdr location)
+                           (goto-char (cdr location))
+                         (message "Unable to find location in file")))))
+  'help-echo (purecopy "mouse-2, RET: find function's definition"))
+
+(defun info-compile-emacs-info-dir-content ()
+  "Build a list of file names from Emacs' info directories.
+This function fills `info-emacs-info-dir-content' with files from
+`Info-directory-list'."
+  (setq info-emacs-info-dir-content
+        (mapcar 'file-name-nondirectory
+                (directory-files
+                 (car
+                  ;; search for the main Emacs' info/ directory, when this
+                  ;; function is called Info-directory-list is already
+                  ;; initialised
+                  (cl-member "[^.]emacs" Info-directory-list :test
+                             'string-match-p))
+                 ;; don't list "." and ".."
+                 t  "[^.]$"))))
+
+(defun info-button-action (button)
+  "Call BUTTON's help function."
+  (info-do-xref nil
+                (button-get button 'info-function)
+                (button-get button 'info-args)))
+
+(defun info-do-xref (_pos function args)
+  "Call the help cross-reference function FUNCTION with args ARGS.
+Things are set up properly so that the resulting `help-buffer' has
+a proper [back] button."
+  ;; There is a reference at point.  Follow it.
+  (let ((help-xref-following nil))
+    (apply
+     function (if (eq function 'info)
+                  (append args (list (generate-new-buffer-name "*info*")))args))))
+
+(defun info-button (match-number type &rest args)
+  "Make a hyperlink for cross-reference text previously matched.
+MATCH-NUMBER is the subexpression of interest in the last matched
+regexp.  TYPE is the type of button to use.  Any remaining
+arguments are passed to the button's info-function when it is
+invoked.  See `info-make-links-to-help'.  Don't forget ARGS."
+  ;; Don't munge properties we've added, especially in some instances.
+  (unless (button-at (match-beginning match-number))
+    (make-text-button (match-beginning match-number)
+                      (match-end match-number)
+                      'type type 'info-args args)))
+
+(defvar info-symbol-context
+  '((variable . "variable\\|option")
+    (function . "function\\|command\\|call")
+    (face . "face")
+    ;; ignore symbols following this context type
+    (ignore . "symbol\\|program\\|property")
+    ;; function definitions in files
+    (definition . "source \\(?:code \\)?\\(?:of\\|for\\)"))
+  "This list helps to distinguish symbol types.
+Words in info documentation preceding a (quoted) symbol are used
+to distinguish variables, functions, faces and symbols.  The
+context information can also be used to ignore symbols because
+there is no help documentation for them.  The strings of the the
+list are becoming part of `info-symbol-regexp'.")
+
+(defvar info-symbol-regexp
+  ;; better use purecopy?
+  (concat
+   "\\("                                ; Context start
+   "\\<\\("                             ; Contex type definition
+   (string-remove-suffix
+    "\\|"
+    (mapconcat
+     (lambda (x) (concat "\\(" (cdr x) "\\)\\|"))
+     info-symbol-context ""))
+   "\\)"          ; Context type definition end
+   "[ \t\n]+"     ; Separators to quoted symbols
+   "\\)?"         ; End of context
+   ;; quoted symbol
+   "['`‘]"	  ; opening quotes
+   ;; Note: Symbol starting with word-syntax character:
+   "\\(\\sw\\(\\sw\\|\\s_\\)+\\|`\\)" ; The symbol itself
+   "['’]"                             ; End quotes
+   )
+  "The regular expression for matching symbols to their help documentation.
+It is comprised of the symbol's context and the (quoted) symbol
+name.  The various groups of context regular expressions are
+matched in `info-make-links-to-help' to distinct info buttons.")
+
+(defun info-check-type( type)
+  "Check if TYPE corresponds to the current search result.
+The function is used in `info-make-links-to-help'."
+  (let* ((isc info-symbol-context)
+	 (n 3)                          ;embedded within 2 groups
+         (l (+ 3 (length isc))))
+    (while (and (not (eq type (caar isc) ) ) (< n l) )
+      (setq n (1+ n))
+      (setq isc (cdr isc)))
+    (match-string n)))
+
+\f
+;;;###autoload
+(defun info-make-links-to-help (&optional buffer)
+  "Parse and hyperlink quoted symbols in the given BUFFER.
+BUFFER defaults to the current buffer if omitted or nil.  Find
+symbols and their context in an Info buffer and activate buttons
+for linking to their documentation string with `info-button'.
+
+Symbols have the canonical (quoted) form `symbol-name' and the
+type of reference may be disambiguated by the preceding word(s)
+as compiled in `info-symbol-regexp'.  For example: Symbol names
+are receiving distinct variable buttons when preceeded by the
+words \"variable\" or \"option\".
+
+Variables are also detected when their names follow below forms:
+
+ -- User Option: variable-name
+ -- Variable: ...
+
+Function names are detected when prefixed by `M-x', for example
+`M-x function-name' or are quoted and prefixed like `M-x
+function-name'.
+
+Function names are detected, as well, when appearing behind the
+following forms, which occur - for example - in the Elisp manual:
+
+ -- Special Form: function-name
+ -- Command: ...
+ -- Function: ...
+ -- Macro: ...
+
+The linking is similar to mechanisms from lisp/help.el."
+  (interactive "b")                     ;asking for buffer name..
+  (if (eq major-mode 'Info-mode)
+      (when (info-check-docu-p)
+        (with-current-buffer (or buffer (current-buffer))
+          (save-excursion
+            (goto-char (point-min))
+            (with-silent-modifications
+              (let ((case-fold-search t)
+                    (inhibit-read-only t))
+                (with-syntax-table emacs-lisp-mode-syntax-table
+                  ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+                  ;; The following is for finding "quoted symbols"
+                  (save-excursion
+                    (while (re-search-forward info-symbol-regexp nil t)
+                      ;; sym-group is the regexp group for the symbol name
+                      (let* ((sym-group (+ 3 (length info-symbol-context)))
+                             (data (match-string sym-group))
+                             (sym (intern-soft data)))
+                        (if sym
+                            (cond
+                             ((info-check-type 'variable)
+                              (and (or (boundp sym)
+                                       (get sym 'variable-documentation))
+                                   (info-button sym-group 'info-variable sym)))
+                             ((info-check-type 'function)
+                              (and (fboundp sym)
+                                   (info-button sym-group 'info-function sym)))
+                             ((info-check-type 'face)
+                              (and (facep sym)
+                                   (info-button sym-group 'info-face sym)))
+                             ((info-check-type 'ignore))
+                             ((info-check-type 'definition)
+                              (info-button sym-group 'info-function-def sym))
+                             ;; for symbols
+                             ((cl-some (lambda (x) (funcall (nth 1 x) sym))
+                                       describe-symbol-backends)
+                              (info-button sym-group 'info-symbol sym)))))))
+                  ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+                  ;; See e.g.: (info "(elisp) Eval")
+                  ;; Elisp manual      -- Special Form:
+                  ;;                   -- Command:
+                  ;;                   -- Function: function-name function
+                  ;;                   -- Macro:
+                  (save-excursion
+                    (while (re-search-forward
+                            "-- \\(Special Form:\\|Command:\\|Function:\\|Macro:\\) "
+                            nil t)
+                      (looking-at "\\(\\sw\\|\\s_\\)+")
+                      (let ((sym (intern-soft (match-string 0))))
+                        (if (fboundp sym)
+                            (info-button 0 'info-function sym)))))
+                  ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+                  ;;              -- User Option:
+                  ;;              -- Variable: variable-name
+                  (save-excursion
+                    (while (re-search-forward
+                            "-- \\(User Option:\\|Variable:\\) "
+                            nil t)
+                      (looking-at "\\(\\sw\\|\\s_\\)+")
+                      (let ((sym (intern-soft (match-string 0))))
+                        (if (boundp sym)
+                            (info-button 0 'info-variable sym)))))
+                  ;; M-x prefixed functions
+                  (save-excursion
+                    (while (re-search-forward
+                            ;; Assume command name is only word and symbol
+                            ;; characters to get things like `use M-x foo->bar'.
+                            ;; Command required to end with word constituent
+                            ;; to avoid `.' at end of a sentence.
+                            ;; "\\<M-x\\s-+\\(\\sw\\(\\sw\\|\\s_\\)*\\sw\\)" nil t)
+                            ;; include M-x and quotes
+                            "['`‘]?M-x\\s-*\n?\\(\\sw\\(\\sw\\|\\s_\\)*\\sw\\)['’]?" nil t)
+                      (let ((sym (intern-soft (match-string 1))))
+                        (if (fboundp sym)
+                            (info-button 1 'info-function sym)))))))))))
+    ;; other, non-Info buffers
+    (info--buttonize)
+    ))
+
+;; stolen from emacs-news-mode.el
+(defun info--buttonize ()
+  "Make manual and symbol references into buttons."
+  (save-excursion
+    (with-silent-modifications
+      (let ((inhibit-read-only t))
+        ;; Do functions and variables.
+        (goto-char (point-min))
+        (search-forward "\f" nil t)
+        ;; symbol quoting styles: '' and `' (grave accent and
+        ;; apostrophe, pre Emacs-25)
+        (while (re-search-forward "['`]\\([^-][^ \t\n]+\\)'" nil t)
+          ;; Filter out references to key sequences.
+          (let ((string (match-string 1)))
+            (when-let ((symbol (intern-soft string)))
+              (when (or (boundp symbol)
+                        (fboundp symbol))
+                (buttonize-region (match-beginning 1) (match-end 1)
+                                  (lambda (symbol)
+                                    (describe-symbol symbol))
+                                  symbol)))))
+        ;; Do manual references '"(...) ..."'.
+        (goto-char (point-min))
+        (search-forward "\f" nil t)
+        (while (re-search-forward "\"\\(([a-z0-9-]+)[ \n][^\"]\\{1,80\\}\\)\""
+                                  nil t)
+          (buttonize-region (match-beginning 1) (match-end 1)
+                            (lambda (node) (info node))
+                            (match-string 1)))))))
+
+
 (provide 'info)
 
 ;;; info.el ends here
-- 
2.34.1


[-- Attachment #3: Type: text/plain, Size: 56 bytes --]


-- 
Best wishes
H. Dieter Wilhelm
Zwingenberg, Germany

^ permalink raw reply related	[flat|nested] 58+ messages in thread

* bug#60587: Patch for adding links to symbols' help documentation
  2023-03-01 21:45                                     ` H. Dieter Wilhelm
@ 2023-03-11  8:32                                       ` Eli Zaretskii
  2023-03-11  9:16                                         ` H. Dieter Wilhelm
  0 siblings, 1 reply; 58+ messages in thread
From: Eli Zaretskii @ 2023-03-11  8:32 UTC (permalink / raw)
  To: H. Dieter Wilhelm; +Cc: juri, 60587, monnier, drew.adams

> From: "H. Dieter Wilhelm" <dieter@duenenhof-wilhelm.de>
> Cc: Drew Adams <drew.adams@oracle.com>,  Eli Zaretskii <eliz@gnu.org>,
>   "60587@debbugs.gnu.org" <60587@debbugs.gnu.org>,  Juri Linkov
>  <juri@jurta.org>
> Date: Wed, 01 Mar 2023 22:45:06 +0100
> 
> Tags: patch
> 
> Stefan Monnier <monnier@iro.umontreal.ca> writes:
> 
> >> The only thing, which feels strange to me, is that
> >> 'info-links-to-help-mode' is now a minor mode for all buffers (and
> >> modes).  Sure, it's only affecting 'Info-mode' but isn't there a way of
> >> making it a "global" minor mode only for Info buffers?  Anyway, I
> >> couldn't find a way to restrict global minor modes to certain major
> >> modes.
> >
> > No it's perfectly normal to have a global preference that only affects
> > the buffers for which it's relevant.  I like my food to be spicy and
> > that's just as true when I eat as when I don't but it has consequences
> > only when I do.
> >
> 
> Alright :-)
> 
> I've adjusted the code and documentation accordingly and created another
> patch.

Thanks.  I tried to install this, but the patch doesn't apply.  So
please resubmit so it applies to the current master branch.

While at that, please accompany the patch with a commit log message
per our coding standards: it should be a ChangeLog-style list of new
and modified functions, variables and manual nodes, each one with a
short description of the change you made there.  See CONTRIBUTE for
the description of our conventions (search for "ChangeLog") and of
useful Emacs commands that will help you format the log message
according to the conventions.





^ permalink raw reply	[flat|nested] 58+ messages in thread

* bug#60587: Patch for adding links to symbols' help documentation
  2023-03-11  8:32                                       ` Eli Zaretskii
@ 2023-03-11  9:16                                         ` H. Dieter Wilhelm
  0 siblings, 0 replies; 58+ messages in thread
From: H. Dieter Wilhelm @ 2023-03-11  9:16 UTC (permalink / raw)
  To: Eli Zaretskii; +Cc: juri, 60587, monnier, drew.adams

Eli Zaretskii <eliz@gnu.org> writes:

>> I've adjusted the code and documentation accordingly and created another
>> patch.
>
> Thanks.  I tried to install this, but the patch doesn't apply.  So
> please resubmit so it applies to the current master branch.

Before patch creation I fetched the current master branch in my feature
branch and built it on top.  Either something changed in the meantime
"near" the chunks or I made a stupid mistake.  I'll recreate a patch and
check it before sending.  I'm sorry for your wasted time.

> While at that, please accompany the patch with a commit log message
> per our coding standards: it should be a ChangeLog-style list of new
> and modified functions, variables and manual nodes, each one with a
> short description of the change you made there.  See CONTRIBUTE for
> the description of our conventions (search for "ChangeLog") and of
> useful Emacs commands that will help you format the log message
> according to the conventions.

I'll do so.

-- 
Thank you for your patience

   Dieter
   
Best wishes
H. Dieter Wilhelm
Zwingenberg, Germany





^ permalink raw reply	[flat|nested] 58+ messages in thread

end of thread, other threads:[~2023-03-11  9:16 UTC | newest]

Thread overview: 58+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2023-01-05 23:47 bug#60587: 30.0.50; Info pages are lacking links from symbol names to the symbol's help documentation H. Dieter Wilhelm
2023-01-06 19:03 ` bug#60587: Patch for adding links to symbols' " H. Dieter Wilhelm
2023-01-07  7:38   ` Eli Zaretskii
2023-01-08 20:06     ` H. Dieter Wilhelm
2023-01-09 12:46       ` Eli Zaretskii
2023-01-09 14:25         ` Stefan Monnier via Bug reports for GNU Emacs, the Swiss army knife of text editors
2023-01-09 20:01         ` H. Dieter Wilhelm
2023-01-13 23:33     ` H. Dieter Wilhelm
2023-01-14  7:12       ` Eli Zaretskii
2023-01-15 12:48         ` H. Dieter Wilhelm
2023-01-17 21:53     ` H. Dieter Wilhelm
2023-01-18 13:20       ` Eli Zaretskii
2023-01-20 21:09         ` H. Dieter Wilhelm
2023-01-20 21:59           ` Drew Adams
2023-01-20 23:32           ` Stefan Monnier via Bug reports for GNU Emacs, the Swiss army knife of text editors
2023-01-22 13:00             ` H. Dieter Wilhelm
2023-01-21  8:21           ` Eli Zaretskii
2023-01-21 20:27             ` H. Dieter Wilhelm
2023-01-22  6:00               ` Eli Zaretskii
2023-01-22 22:09                 ` Drew Adams
2023-01-23 12:14                   ` Eli Zaretskii
2023-01-23 16:16                     ` Drew Adams
2023-01-25 21:29             ` H. Dieter Wilhelm
2023-01-25 22:24               ` Drew Adams
2023-01-26 10:29                 ` Ihor Radchenko
2023-01-26 15:06                   ` Drew Adams
2023-01-26 15:12                     ` Ihor Radchenko
2023-01-26 15:23                       ` Drew Adams
2023-01-27 21:35                 ` H. Dieter Wilhelm
2023-01-27 22:12                   ` Stefan Monnier via Bug reports for GNU Emacs, the Swiss army knife of text editors
2023-01-27 23:09                     ` Drew Adams
2023-01-27 23:13                   ` Drew Adams
2023-01-28  8:11                     ` Eli Zaretskii
2023-01-28 17:30                       ` Drew Adams
2023-02-01 22:09                     ` H. Dieter Wilhelm
2023-02-02  2:30                       ` Drew Adams
2023-02-05  0:48                     ` H. Dieter Wilhelm
2023-02-05  3:54                       ` Stefan Monnier via Bug reports for GNU Emacs, the Swiss army knife of text editors
2023-02-05 13:54                         ` H. Dieter Wilhelm
2023-02-06 21:04                           ` H. Dieter Wilhelm
2023-02-12 11:04                         ` H. Dieter Wilhelm
2023-02-14 20:56                           ` Stefan Monnier via Bug reports for GNU Emacs, the Swiss army knife of text editors
2023-02-15 22:18                             ` H. Dieter Wilhelm
2023-02-16  3:08                               ` Stefan Monnier via Bug reports for GNU Emacs, the Swiss army knife of text editors
2023-02-20 23:53                                 ` H. Dieter Wilhelm
2023-02-21  2:12                                   ` Stefan Monnier via Bug reports for GNU Emacs, the Swiss army knife of text editors
2023-03-01 21:45                                     ` H. Dieter Wilhelm
2023-03-11  8:32                                       ` Eli Zaretskii
2023-03-11  9:16                                         ` H. Dieter Wilhelm
2023-02-15  5:17                           ` Richard Stallman
2023-02-15  9:53                             ` Gregory Heytings
2023-02-15 13:42                               ` Gregory Heytings
2023-01-26 10:37               ` Eli Zaretskii
2023-01-27  7:45                 ` Juri Linkov
2023-01-27  8:11                   ` Eli Zaretskii
2023-01-27 22:21                 ` H. Dieter Wilhelm
2023-01-28  7:51                   ` Eli Zaretskii
2023-02-01 21:26                 ` H. Dieter Wilhelm

Code repositories for project(s) associated with this public inbox

	https://git.savannah.gnu.org/cgit/emacs.git

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).