From ced50f255d0895e7b30720717451ce3dfc970ad3 Mon Sep 17 00:00:00 2001 From: Greg Hendershott Date: Fri, 1 Dec 2023 12:36:52 -0500 Subject: [PATCH] Improve racket-bug-report This was motivated by issue #683 where I realized the collected details weren't sufficient, as well as somewhat outdated, resulting in me needing to ask more basic questions than should be necessary. So: Give error when not run from a racket-xxx buffer, because we want information specific to the buffer where someone is having a problem. Collect more information, including some popular hooks, as well as whether the back end is running. Automatically include all values from racket-custom, so that the list will remain more up-to-date (although we still manually include some variable of interest that aren't customization variables). Emit markdown to present using section headers as well as definition lists (using HTML dl, dt, and dd elements). --- racket-bug-report.el | 150 +++++++++++++++++++++++++------------------ 1 file changed, 87 insertions(+), 63 deletions(-) diff --git a/racket-bug-report.el b/racket-bug-report.el index a0109619..6d1acc65 100644 --- a/racket-bug-report.el +++ b/racket-bug-report.el @@ -1,6 +1,6 @@ ;;; racket-bug-report.el -*- lexical-binding: t; -*- -;; Copyright (c) 2013-2022 by Greg Hendershott. +;; Copyright (c) 2013-2023 by Greg Hendershott. ;; Portions Copyright (C) 1985-1986, 1999-2013 Free Software Foundation, Inc. ;; Author: Greg Hendershott @@ -8,81 +8,105 @@ ;; SPDX-License-Identifier: GPL-3.0-or-later -(require 'cl-lib) +(require 'cl-macs) +(require 'cus-edit) (require 'package) +(require 'seq) +(require 'racket-back-end) +(require 'racket-cmd) (require 'racket-custom) ;;;###autoload (defun racket-bug-report () "Fill a buffer with data to make a Racket Mode bug report." (interactive) + (unless (string-match-p "^racket-" (symbol-name major-mode)) + (user-error "Please run from a Racket Mode buffer in which you're having a problem")) (let ((help-window-select t) (print-length nil) ;for `pp' (print-level nil)) ;for `pp' - (with-help-window "*racket-mode bug report*" - (princ "Please copy all of the following lines and paste them into your bug report\n") - (princ "at .\n\n") + (cl-flet ((p (label value) + (princ (format "
%s
" label)) + (princ "
")
+                 (pp value)
+                 (princ "
\n")) + (section (label thunk) + (princ (format "

%s

\n" label)) + (princ "
\n") + (funcall thunk) + (princ "
\n")) + (symbol-less-p (a b) (string-lessp (symbol-name a) (symbol-name b)))) + (with-help-window "*racket-mode bug report*" + (princ "Please copy all of the following lines and paste them into your bug report\n") + (princ "at .\n\n") - (princ "
\n") - (princ "
\n")
-      (pp (cons '(alist-get 'racket-mode package-alist)
-                (let ((v (assq 'racket-mode package-alist)))
-                  (and v (cdr v)))))
-      (cl-flet ((id-val (id) (list id
-                                   (condition-case () (symbol-value id)
-                                     (error 'UNDEFINED)))))
-        (pp `(,@(mapcar #'id-val
-                        `(emacs-version
-                          system-type
-                          x-gtk-use-system-tooltips
-                          major-mode
-                          racket--el-source-dir
-                          racket--rkt-source-dir
-                          racket-program
-                          racket-command-timeout
-                          racket-path-from-emacs-to-racket-function
-                          racket-path-from-racket-to-emacs-function
-                          racket-browse-url-function
-                          racket-documentation-search-location
-                          racket-xp-after-change-refresh-delay
-                          racket-xp-mode-lighter
-                          racket-xp-highlight-unused-regexp
-                          racket-repl-buffer-name-function
-                          racket-submodules-to-run
-                          racket-memory-limit
-                          racket-error-context
-                          racket-repl-history-directory
-                          racket-history-filter-regexp
-                          racket-images-inline
-                          racket-imagemagick-props
-                          racket-images-keep-last
-                          racket-images-system-viewer
-                          racket-pretty-print
-                          racket-use-repl-submit-predicate
-                          racket-pretty-print
-                          racket-indent-curly-as-sequence
-                          racket-indent-sequence-depth
-                          racket-pretty-lambda
-                          racket-smart-open-bracket-enable
-                          racket-module-forms
-                          racket-logger-config
-                          racket-show-functions))))
-        ;; Show lists of enabled and disabled minor modes, each sorted by name.
-        (let* ((minor-modes (cl-remove-duplicates
-                             (append minor-mode-list
-                                     (mapcar #'car minor-mode-alist))))
-               (modes/values (mapcar #'id-val minor-modes))
-               (sorted (sort modes/values
-                             (lambda (a b)
-                               (string-lessp (format "%s" (car a))
-                                             (format "%s" (car b)))))))
-          (cl-flet ((f (x) (list (car x)))) ;car as a list so pp line-wraps
-            (pp `(enabled-minor-modes  ,@(mapcar #'f (cl-remove-if-not #'cadr sorted))))
-            (pp `(disabled-minor-modes ,@(mapcar #'f (cl-remove-if     #'cadr sorted)))))))
-      (princ "
\n") - (princ "
\n")) + (princ "
\n") + (section "Package" + (lambda () + (p "Metadata" + (let ((v (assq 'racket-mode package-alist))) + (and v (cdr v)))))) + (section "General values" + (lambda () + (dolist (sym '(emacs-version + major-mode + system-type + x-gtk-use-system-tooltips + after-change-functions + completion-at-point-functions + eldoc-documentation-function + font-lock-defaults + xref-backend-functions)) + (ignore-errors + (p sym (symbol-value sym)))) + (dolist (fun (list #'display-graphic-p)) + (ignore-errors + (p fun (funcall fun)))))) + (section "Racket Mode values" + (lambda () + (p 'racket--cmd-open-p (racket--cmd-open-p)) + (dolist (sym + (sort (append (racket--bug-report-customs) + '(racket-mode-hook + racket-hash-lang-mode-hook + racket-hash-lang-module-language-hook + racket-repl-mode-hook + racket-back-end-configurations + racket--el-source-dir + racket--rkt-source-dir)) + #'symbol-less-p)) + (p sym (symbol-value sym))))) + (section "Minor modes" + (lambda () + (let* ((minor-modes (seq-uniq + (append minor-mode-list + (mapcar #'car minor-mode-alist)))) + (minor-modes (sort minor-modes #'symbol-less-p)) + (enabled (seq-filter (lambda (sym) + (when (ignore-errors (symbol-value sym)) + sym)) + minor-modes)) + (disabled (seq-filter (lambda (sym) + (unless (ignore-errors (symbol-value sym)) + sym)) + minor-modes))) + (p 'enabled (mapcar #'list enabled)) ;so pp line-breaks + (princ "
Disabled minor modes\n") + (p 'disabled (mapcar #'list disabled)) + (princ "
\n")))) + (princ "
\n\nSteps to reproduce: "))) (forward-line 2))) +(defun racket--bug-report-customs () + (let ((syms nil)) + (cl-labels ((item (v) (pcase v + (`(,sym custom-variable) (push sym syms)) + (`(,sym custom-group) (group sym)))) + (group (sym) (dolist (v (custom-group-members sym nil)) + (item v)))) + (group 'racket) + syms))) + (provide 'racket-bug-report) ;;; racket-bug-report.el ends here