Subject: help-make-xref doesn't buttonize `help-variable-def' and per `help-xref-symbol-regexp'

From: MON KEY <[email-masked]>
Date: Mon, 12 Jul 2010 22:10:47 -0400

;;; ==============================
;;;
;;; Following illustrates a proof of concept for how to correct the problem.
;;;
;;; ==============================

(defvar *help-xref-ascii-symbol-vars-test*
  '("`!some-var-bang!'"  "`@colonel-at-var@'" "`$some-rich-var$'"
    "`%percenta-var%'" "`+var-plus-plus+'" "`-dash-var-'" "`--morse-.-var--'"
    "`.dot-var.'"  "`/slash-var/'" "`\\bkslsh-var\\'" "`/pyra-var\'"
    "`\\funnel-var/'" "`=equi-var='" "`>greata-var>'" "`<lesser-var<'"
    "`>meow-var<'" "`<entity-var>'" "`?var-quest?'"  "`^up-var^'"
"`_under-var_'"
    "`{open-var{'" "`}close-var}'" "`|bar-var|'" "`{pair-brc-var}'"
    "`}invrted-brc-var{'")
  "List of strings to test for with `help-xref-modify-symbols-syntax-table-TEST'
Each string is preceded and followed a char in
`*help-xref-ascii-symbol-vars*'.")

(defvar *help-xref-ascii-symbol-vars*
  '(33  ;; !
    36  ;; $
    37  ;; %
    42  ;; *
    43  ;; +
    45  ;; -
    46  ;; .
    47  ;; /
    64  ;; @
    60  ;; >
    61  ;; =
    62  ;; >
    63  ;; ?
    92  ;; /
    94  ;; ^
    95  ;; _
    123 ;; {
    124 ;; |
    125 ;; }
    )
  "A list of characters that `help-make-xrefs' does not recognize when
buttonizing if they appear as the first char of a symbol name.")

(defvar *help-xref-ascii-symbol-vars-regexp*
  ;; "\\(\\s(\\(\\(\\sw\\|\\s_\\)+\\)\\s)\\)"
  ;;  ^^1^^^^^^^^^2^^^^^^^^^^^^^^^^^^^^^^^^
  (concat "\\("  ;; grp1
          "\\s(" ;; open-paren -> `
          "\\("  ;; grp2
          "\\(\\sw\\|\\s_\\)+"
          "\\)"
          "\\s)" ;; close-paren -> '
          "\\)")
  "Regexp for finding symbols preceded and followed a char in the variable
`*help-xref-ascii-symbol-vars*'. Evaluated with a modified syntax table
by `help-xref-modify-symbols-syntax-table-TEST'.")

(defun help-xref-modify-symbols-syntax-table-TEST  ()
  "Function is as a proof of conciept for how to fix `help-make-xrefs'.\n
When *Help* is buttonized it inherits `emacs-lisp-mode-syntax-table' in shuch
a way that the `help-make-xrefs' loop fails to match symbols preceded by certain
ASCII chars. Following table an example of the unmodified *Help*
buffer syntax:\n
 `*some-var*'
 132222222231\n
Where the above table maps the syntax values:\n
 1 <- punct
 3 <- symbol
 2 <- word\n
This function temporarily modifies the syntax table and use the regexp in
`*help-xref-ascii-symbol-vars-regexp*' to identify the test symbols in
`*help-xref-ascii-symbol-vars-test*' by setting each elt of
`*help-xref-ascii-symbol-vars*' to have the \"_\" syntax.\n
We modify chars 40 and 41 \"(\" \")\" to have \".\" syntax.\n
We modify char 96 ASCII grave to have to have \"('\" syntax and delimit it with
the matching char 39 (apostrophe) by giving it the syntax \")`\".\n
Return and display results in buffers named:
 \"*TEST-SYNTAX*\" and  \"*TEST-SYNTAX-RESULTS*\"\n
Return a list of results with the form:\n
 \(:length-test-list <LENGTH-OF-LIST-TESTED>
  :matched-all-p { t | nil }
  :found-these   \(\"LIST\" \"OF\" \"STRINGS\" \"FOUND\"\)
  :with-these    \(\"`LIST'\" \"`OF'\" \"`STRINGS'\"
\"`FOUND-PRE-SYNTAX-FROB'\"\)\)\n
Assuming value of property :matched-all-p is t the list of the :found-these
property could be buttonized by `help-make-xrefs'.\n
:EXAMPLE\n\n\(help-xref-modify-symbols-syntax-table-TEST\)\n"
  (with-current-buffer (get-buffer-create "*TEST-SYNTAX*")
    (erase-buffer)
    (display-buffer (current-buffer) t)
    (let ((xref-syms ;;(copy-syntax-table emacs-lisp-mode-syntax-table))
           (make-syntax-table emacs-lisp-mode-syntax-table))
          (syn-syms *help-xref-ascii-symbol-vars*)
          gthr-syn)
      (dolist (syn syn-syms)
        (modify-syntax-entry syn "_" xref-syms))
      ;; turn-off parens
      (modify-syntax-entry 40  "." xref-syms)
      (modify-syntax-entry 41  "." xref-syms)
      ;; make ` <- (
      (modify-syntax-entry 96  "('" xref-syms)
      ;; make ' <- )
      (modify-syntax-entry 39  ")`" xref-syms)
      ;; push (match-string-no-properties 2) gthr-syn))
      (save-excursion
        (insert (mapconcat #'identity *help-xref-ascii-symbol-vars-test* "\n")))
      (with-syntax-table xref-syms
        (while (search-forward-regexp
*help-xref-ascii-symbol-vars-regexp* nil t)
          (push (match-string-no-properties 2) gthr-syn)))
      (setq gthr-syn
            `(:length-test-list ,(length *help-xref-ascii-symbol-vars-test*)
                                :matched-all-p  ,(eq (length gthr-syn)
                                                     (length
*help-xref-ascii-symbol-vars-test*))
                                :found-these ,(nreverse gthr-syn)
                                :with-these
,*help-xref-ascii-symbol-vars-test*))
      (kill-buffer (get-buffer-create "*TEST-SYNTAX-RESULTS*"))
      (pp-display-expression gthr-syn "*TEST-SYNTAX-RESULTS*")
      (pop-to-buffer "*TEST-SYNTAX*" t)
      (pop-to-buffer "*TEST-SYNTAX-RESULTS*" t)
      gthr-syn)))
;;
;; (help-xref-modify-symbols-syntax-table-TEST)

;;; ==============================

Function `help-make-xrefs' performs its xref'ing inside an unwind-protect
searching matches for the following regexps:
`help-xref-info-regexp', `help-xref-url-regexp',
`help-xref-mule-regexp', `help-xref-symbol-regexp',
with matches buttonized accordingly.

It seems the sole purpose of the `unwind-protect' for is to rebind the buffer's
syntax to the value stashed away in the local variable `stab'.

Is there some reason why `help-make-xrefs' shouldn't be doing this inside of
the `with-syntax-table' macro? e.g.

 (with-syntax-table emacs-lisp-mode-syntax-table
   {... frob xrefs here ... } )

 Also, can this:

  (let ((old-modified (buffer-modified-p)))

be replaced by a wrap with the macro: `with-silent-modifications'

;;; ==============================

Revised version of previous file attatched.