GNU bug report logs - #6601
help-make-xref doesn't buttonize `help-variable-def' and per `help-xref-symbol-regexp'

Previous Next

Package: emacs;

Reported by: MON KEY <monkey <at> sandpframing.com>

Date: Sat, 10 Jul 2010 01:10:02 UTC

Severity: minor

Tags: fixed, patch

Merged with 24309

Found in version 25.1

Fixed in version 28.1

Done: "Basil L. Contovounesios" <contovob <at> tcd.ie>

Bug is archived. No further changes may be made.

To add a comment to this bug, you must first unarchive it, by sending
a message to control AT debbugs.gnu.org, with unarchive 6601 in the body.
You can then email your comments to 6601 AT debbugs.gnu.org in the normal way.

Toggle the display of automated, internal messages from the tracker.

View this report as an mbox folder, status mbox, maintainer mbox


Report forwarded to owner <at> debbugs.gnu.org, bug-gnu-emacs <at> gnu.org:
bug#6601; Package emacs. (Sat, 10 Jul 2010 01:10:03 GMT) Full text and rfc822 format available.

Acknowledgement sent to MON KEY <monkey <at> sandpframing.com>:
New bug report received and forwarded. Copy sent to bug-gnu-emacs <at> gnu.org. (Sat, 10 Jul 2010 01:10:03 GMT) Full text and rfc822 format available.

Message #5 received at submit <at> debbugs.gnu.org (full text, mbox):

From: MON KEY <monkey <at> sandpframing.com>
To: bug-gnu-emacs <at> gnu.org
Subject: help-make-xref doesn't buttonize `help-variable-def' and per 
	`help-xref-symbol-regexp'
Date: Fri, 9 Jul 2010 21:09:22 -0400
[Message part 1 (text/plain, inline)]
The button `help-variable-def' and constant `help-xref-symbol-regexp'
do not find variables with symbol-names containing asterisks,
e.g. `*some-var*'. Presumably this applies equally as well to any
variable which contains a non-letter as the first character in the
variables symbol name.

It looks like `help-make-xrefs' inherits the
`emacs-lisp-mode-syntax-table' and odd stuff is happening around the
regexp and the syntax table though this seems odd as `*' is a symbol
constituent.

Following bit of code provides an example illustrating the problem:


(defvar check-xref-var-no-star 'xrefd-in-docstrings
  "A test for xref'ing non-star prefixed variables in docstrings.\n
Non-star prefixed variables have the form:\n
 <SOME-VAR-NAME>\n
These appear with xrefs in docstrings when preceded by either of the following
two tokens:\n
 { variable | option }\n
where the variables symbol-name is enclosed with a preceding grave char `
\(ASCII 96\), and followed by an apostrophe char ' (ASCII 39) e.g.:\n
 variable `<SOME-VAR-NAME>'
 option `<SOME-VAR-NAME>'\n
This is as contrasted with star prefixed variables which have the form:\n
 *<SOME-VAR-NAME>*\n
and do not appear with xrefs in docstrings.\n
For example, this variable `*check-xref-var-w-star*' is not xref'd.
Neither is it xref'd as an option `*check-xref-var-w-star*'.
However, the current variable `check-xref-var-no-star' is xref'd.
Likewise, it is also xref'd as the option `check-xref-var-no-star'.")

(defvar *check-xref-var-w-star* 'not-xrefd-in-docstrings
  "A test for xref'ing star prefixed variables in docstrings.\n
Star prefixed variables have the form:\n
 *<SOME-VAR-NAME>*\n
these do not appear with xrefs in docstrings.\n
This is as contrasted with non-star prefixed variables which have the form:\n
  <SOME-VAR-NAME>\n
and which do appear in xref'd in docstrings when preceded by either of the
follwing two tokens:\n
 { variable | option }\n
where the symbole-name of the variable is enclosed with a preceding grave char `
\(ASCII 96\) and followed by an apostrophe char ' (ASCII 39) e.g.:\n
 variable `<SOME-VAR-NAME>'
 option `<SOME-VAR-NAME>'\n
For example, this variable `check-xref-var-no-star' is xref'd.
Likewise, the option `check-xref-var-no-star' is also xref'd.
Whereas, the variable `*check-xref-var-w-star*' is not xref'd.
Neither is it xref'd as option `*check-xref-var-w-star*'.")

(defun check-xref-test-function ()
  "This is a docstring which tests xref'ing of two differently named
variables.\n
The current functions docstring illustrates the problem.\n
This symbol-name will be xref'd as variable `check-xref-var-no-star'.\n
It will also be xref'd as option `check-xref-var-no-star'.\n
Whereas following symbol-name is not xref'd as variable
`*check-xref-var-w-star*',
nor is it xref'd as option `*check-xref-var-w-star*'.\n
This behaviour constitutes a bug. For additional detailed illustration of the
problem see return value of `check-xrefs-w-help-variable-def'."
  (describe-function 'check-xref-test-function))

(defun check-xrefs-w-help-variable-def (&optional w-test-fncn cnt-var-name)
  "Find help-variable-button text-property values in *Help* buffer.\n
Return a list of text-properties and buffer locations when buffer has
a `category` text-property with a prop value `help-variable-button`.\n
List contains a count of the number of times the property `help-variable-button`
appears along with the count of the number of times a variable name appears in
the documentation.\n
When W-TEST-FNCN is non-nil it is a symol naming a documented function.
Default is `check-xref-test-function'.\n
When CNT-VAR-NAME is non-nil count the number of times symbol-name matches the
regexp \"`<CNT-VAR-NAME>'\".
Default is to count matches for the symbol `*check-xref-var-w-star*'.\n
Before returning pops-to-buffer named \"*Help*\" and then to buffer named
\"*CHECK-XREFS-W-HELP-VARIABLE-DEF*\".\n
:EXAMPLE\n\n\(check-xrefs-w-help-variable-def\)\n
\(check-xrefs-w-help-variable-def 'help-make-xrefs 'help-forward-label\)\n
\(check-xrefs-w-help-variable-def 'help-make-xrefs 'help-xref-symbol-regexp\)\n"
  (let ((gthr-props)
        (gthrng t))
    (if w-test-fncn
        (describe-function w-test-fncn)
      (check-xref-test-function))
    (with-current-buffer
        (get-buffer "*Help*")
      (goto-char (buffer-end 0))
      (while gthrng
        (when (eq (point) (buffer-end 0))
          (goto-char (next-single-property-change (point) 'button)))
        (unless (null (text-properties-at (point)))
          (let* ((props-here (text-properties-at (point)))
                 (chk-hvb (plist-get props-here 'category)))
            (when (equal (symbol-name chk-hvb) "help-variable-button")
              (push `(:button-found-at ,(point) :w-props ,props-here)
gthr-props))
            (if (eq (next-char-property-change (point)) (point))
                (setq gthrng)
              (progn (goto-char (next-char-property-change (point)))
                     (if (eq (next-char-property-change (point)) (point))
                         (setq gthrng)
                       (let ((chk-nxt (next-single-property-change
(point) 'button)))
                         (if chk-nxt
                             (goto-char (next-single-property-change
(point) 'button))
                           (setq gthrng)))))))))
      (when gthr-props (setq gthr-props (nreverse gthr-props)))
      (let ((cnt-fnd 0))
        (dolist (bfa gthr-props
                     (when (> cnt-fnd 0)
                       (setq gthr-props
                             (nconc `(:help-var-btn-fnd-n-tms
,cnt-fnd) gthr-props))))
          (when (equal (symbol-name (plist-get (plist-get bfa
:w-props) 'category))
                       "help-variable-button")
            (incf cnt-fnd)))
        (goto-char (buffer-end 0))
        (setq cnt-fnd 0)
        (let* ((chk-star-sym (or cnt-var-name '*check-xref-var-w-star*))
               (chk-star-str (format "`\%s\'" chk-star-sym)))
          (while (search-forward-regexp chk-star-str nil t)
            (incf cnt-fnd))
          (if (> cnt-fnd 0)
              (progn
                (setq gthrng 0)
                (dolist (bfa (if (eq (car gthr-props) :help-var-btn-fnd-n-tms)
                                 (cddr gthr-props)
                               gthr-props)
                             gthrng)
                  (when (equal (symbol-name (car (plist-get (plist-get
bfa :w-props) 'help-args)))
                               (symbol-name chk-star-sym))
                    (incf gthrng)))
                (setq gthr-props (nconc `(:help-var-star-seen-n-tms ,cnt-fnd
                                          :help-var-star-seen-n-tms
,gthrng) gthr-props)))
            (setq gthr-props (nconc '(:help-var-star-seen-n-tms 0
                                      :help-var-star-seen-n-tms 0)
gthr-props))))))
    (let ((pp-rtn-bfr "*CHECK-XREFS-W-HELP-VARIABLE-DEF*"))
      (with-current-buffer (get-buffer-create pp-rtn-bfr)
        (erase-buffer))
      (pp-display-expression (identity gthr-props) pp-rtn-bfr)
      (pop-to-buffer "*Help*" t)
      (pop-to-buffer pp-rtn-bfr t))
    gthr-props))

;; :CLEANUP
;; (dolist (unint '(check-xref-var-no-star
;;                  *check-xref-var-w-star*
;;                  check-xref-test-function
;;                  check-xrefs-w-help-variable-def))
;;   (message "The check-xref fncns and vars were uninterned"))
;;; ==============================
[buttonize-help-make-xref.el (application/octet-stream, attachment)]

Information forwarded to owner <at> debbugs.gnu.org, bug-gnu-emacs <at> gnu.org:
bug#6601; Package emacs. (Tue, 13 Jul 2010 02:11:01 GMT) Full text and rfc822 format available.

Message #8 received at 6601 <at> debbugs.gnu.org (full text, mbox):

From: MON KEY <monkey <at> sandpframing.com>
To: 6601 <at> debbugs.gnu.org
Subject: help-make-xref doesn't buttonize `help-variable-def' and per 
	`help-xref-symbol-regexp'
Date: Mon, 12 Jul 2010 22:10:47 -0400
[Message part 1 (text/plain, inline)]
;;; ==============================
;;;
;;; 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.
[bug-6601-buttonize-rev2.el (application/octet-stream, attachment)]

Forcibly Merged 6601 24309. Request was from "Basil L. Contovounesios" <contovob <at> tcd.ie> to control <at> debbugs.gnu.org. (Sun, 27 Dec 2020 19:52:02 GMT) Full text and rfc822 format available.

Removed tag(s) wontfix. Request was from "Basil L. Contovounesios" <contovob <at> tcd.ie> to control <at> debbugs.gnu.org. (Sun, 27 Dec 2020 19:52:02 GMT) Full text and rfc822 format available.

Added tag(s) patch. Request was from "Basil L. Contovounesios" <contovob <at> tcd.ie> to control <at> debbugs.gnu.org. (Sun, 27 Dec 2020 19:52:02 GMT) Full text and rfc822 format available.

Did not alter fixed versions and reopened. Request was from Debbugs Internal Request <help-debbugs <at> gnu.org> to internal_control <at> debbugs.gnu.org. (Sun, 27 Dec 2020 19:56:02 GMT) Full text and rfc822 format available.

Removed tag(s) patch. Request was from "Basil L. Contovounesios" <contovob <at> tcd.ie> to control <at> debbugs.gnu.org. (Sun, 27 Dec 2020 19:56:02 GMT) Full text and rfc822 format available.

Added tag(s) patch. Request was from "Basil L. Contovounesios" <contovob <at> tcd.ie> to control <at> debbugs.gnu.org. (Sun, 27 Dec 2020 19:57:01 GMT) Full text and rfc822 format available.

Added tag(s) fixed. Request was from "Basil L. Contovounesios" <contovob <at> tcd.ie> to control <at> debbugs.gnu.org. (Sun, 10 Jan 2021 13:51:01 GMT) Full text and rfc822 format available.

bug marked as fixed in version 28.1, send any further explanations to 24309 <at> debbugs.gnu.org and Nathanael Schweers <NSchweers <at> mailbox.org> Request was from "Basil L. Contovounesios" <contovob <at> tcd.ie> to control <at> debbugs.gnu.org. (Sun, 10 Jan 2021 13:51:02 GMT) Full text and rfc822 format available.

bug archived. Request was from Debbugs Internal Request <help-debbugs <at> gnu.org> to internal_control <at> debbugs.gnu.org. (Mon, 08 Feb 2021 12:24:03 GMT) Full text and rfc822 format available.

This bug report was last modified 3 years and 98 days ago.

Previous Next


GNU bug tracking system
Copyright (C) 1999 Darren O. Benham, 1997,2003 nCipher Corporation Ltd, 1994-97 Ian Jackson.