]> code.delx.au - gnu-emacs-elpa/blobdiff - packages/bug-hunter/bug-hunter.el
Fix some quoting problems in doc strings
[gnu-emacs-elpa] / packages / bug-hunter / bug-hunter.el
index 0538ac6faba20686f28752dccba197fa92ae9c9d..30c2c8e45ee45dbcb61368868f6d0e36b7c716ec 100644 (file)
@@ -1,10 +1,10 @@
-;;; bug-hunter.el --- Hunt down errors in elisp files  -*- lexical-binding: t; -*-
+;;; bug-hunter.el --- Hunt down errors by bisecting elisp files  -*- lexical-binding: t; -*-
 
 ;; Copyright (C) 2015 Free Software Foundation, Inc.
 
 ;; Author: Artur Malabarba <emacs@endlessparentheses.com>
-;; URL: http://github.com/Malabarba/elisp-bug-hunter
-;; Version: 0.5
+;; URL: https://github.com/Malabarba/elisp-bug-hunter
+;; Version: 1.3.1
 ;; Keywords: lisp
 ;; Package-Requires: ((seq "1.3") (cl-lib "0.5"))
 
@@ -49,8 +49,8 @@
 ;;   ,----
 ;;   | M-x bug-hunter-init-file RET i
 ;;   `----
-;;   The Bug Hunter will start a separate Emacs frame several times, and
-;;   then it will ask you each time whether that frame presented the
+;;   The Bug Hunter will start a separate Emacs instance several times, and
+;;   then it will ask you each time whether that instance presented the
 ;;   problem you have. After doing this about 5--12 times, you’ll be given
 ;;   the results.
 ;;
@@ -98,7 +98,7 @@
 
 (defconst bug-hunter--interactive-explanation
   "You have asked to do an interactive hunt, here's how it goes.
-1) I will start a new Emacs frame.
+1) I will start a new Emacs instance, which opens a new frame.
 2) You will try to reproduce your problem on the new frame.
 3) When you’re done, close that frame.
 4) I will ask you if you managed to reproduce the problem.
 (defconst bug-hunter--assertion-reminder
   "Remember, the assertion must be an expression that returns
 non-nil in your current (problematic) Emacs state, AND that
-returns nil on a clean Emacs instance."
+returns nil on a clean Emacs instance.
+If you're unsure how to write an assertion, you can try the interactive
+hunt instead, or see some examples in the Readme:
+    https://github.com/Malabarba/elisp-bug-hunter"
   "Printed to the user if they provide a bad assertion.")
 
 (defvar bug-hunter--current-head nil
@@ -140,7 +143,10 @@ file.")
               nil)
           (end-of-file `(bug-caught (end-of-file) ,line ,col))
           (invalid-read-syntax `(bug-caught ,er ,line ,col))
-          (error (error "Ran into an error we don't understand, please file a bug report: %S" er)))
+          (error
+           (if (string= (elt er 1) "Invalid modifier in string")
+               `(bug-caught (invalid-modifier) ,line ,col)
+             (error "Ran into an error we don't understand, please file a bug report: %S" er))))
         (nreverse out))))
 
 (defun bug-hunter--read-contents (file)
@@ -212,6 +218,9 @@ the file."
     (cl-case (car error)
       (end-of-file
        "There's a missing closing parenthesis, the expression on this line never ends.")
+      (invalid-modifier (concat "There's a string on this line with an invalid modifier."
+                                "\n  A \"modifier\" is a \\ followed by a few characters."
+                                "\n  For example, \\C-; is an invalid modifier."))
       (invalid-read-syntax
        (let ((char (cadr error)))
          (if (member char '("]" ")"))
@@ -232,7 +241,7 @@ the file."
                             "")
                  (when (> size 16)
                    (format "\n    ... %s omitted expressions ...\n\n"
-                     (- size 14)))
+                           (- size 14)))
                  (when (> size 16)
                    (mapconcat (lambda (x) (bug-hunter--pretty-format x 4))
                               (seq-drop forms (- size 7)) "")))))
@@ -240,7 +249,7 @@ the file."
        (concat "The assertion returned the following value here:\n"
                (bug-hunter--pretty-format (cadr error) 4)))
       (t (format "The following error was signaled here:\n    %S"
-           error))))
+                 error))))
   (when expression
     (bug-hunter--report "  Caused by the following expression:\n%s"
       (bug-hunter--pretty-format expression 4)))
@@ -280,12 +289,12 @@ ARGS are passed before \"-l FILE\"."
       (delete-file file-name))))
 
 (defun bug-hunter--run-form-interactively (form)
-  "Run FORM in a graphical frame and ask user about the outcome."
+  "Run FORM in a graphical instance and ask user about the outcome."
   (let ((file-name (bug-hunter--print-to-temp (list 'prin1 form))))
     (unwind-protect
         (bug-hunter--run-emacs file-name "-Q")
       (delete-file file-name))
-    (y-or-n-p "Did you find the problem/bug in this instance? ")))
+    (y-or-n-p "Did you find the problem/bug in this instance (if you encounter some other issue, answer `n')? ")))
 
 (defun bug-hunter--wrap-forms-for-eval (forms)
   "Return FORMS wrapped in initialization code."
@@ -301,7 +310,7 @@ ARGS are passed before \"-l FILE\"."
   "Execute FORMS in the background and test ASSERTION.
 See `bug-hunter' for a description on the ASSERTION.
 
-If ASSERTION is 'interactive, the form is run through
+If ASSERTION is `interactive', the form is run through
 `bug-hunter--run-form-interactively'.  Otherwise, a slightly
 modified version of the form combined with ASSERTION is run
 through `bug-hunter--run-form'."
@@ -340,16 +349,16 @@ which will be inspected if HEAD doesn't match ASSERTION."
       (vector (length safe) ret-val))
      (ret-val
       (apply #'bug-hunter--bisect
-        assertion
-        safe
-        (bug-hunter--split head)))
+             assertion
+             safe
+             (bug-hunter--split head)))
      ;; Issue in the tail.
      (t (apply #'bug-hunter--bisect
-          assertion
-          (append safe head)
-          ;; If tail has length 1, we already know where the issue is,
-          ;; but we still do this to get the return value.
-          (bug-hunter--split tail))))))
+               assertion
+               (append safe head)
+               ;; If tail has length 1, we already know where the issue is,
+               ;; but we still do this to get the return value.
+               (bug-hunter--split tail))))))
 
 (defun bug-hunter--bisect-start (forms assertion)
   "Run a bisection search on list of FORMS using ASSERTION.
@@ -393,7 +402,7 @@ are evaluated."
     ;; Prepare buffer, and make sure they've seen it.
     (switch-to-buffer (bug-hunter--init-report-buffer assertion bug-hunter--estimate))
     (when (eq assertion 'interactive)
-      (read-char-choice "Please the instructions above and type 6 when ready. " '(?6)))
+      (read-char-choice "Please read the instructions above and type 6 when ready. " '(?6)))
 
     (cond
      ;; Check for errors when reading the init file.
@@ -408,10 +417,12 @@ are evaluated."
         (if assertion
             (concat "The assertion returned nil after loading the entire file.\n"
                     bug-hunter--assertion-reminder)
-          "No errors signaled after loading the entire file. If you're
-looking for something that's not an error, you need to provide an
-assertion. See this link for some examples:
-    https://github.com/Bruce-Connor/elisp-bug-hunter")
+          "No errors signaled after loading the entire file.
+If you're looking for something that's not an error, use the
+interactive hunt instead of the error hunt.  If you have some
+elisp proficiency, you can also use the assertion hunt, see this
+link for some examples:
+    https://github.com/Malabarba/elisp-bug-hunter")
         (or assertion "")))
 
      ;; Make sure we're in a forest, not a volcano.
@@ -420,9 +431,11 @@ assertion. See this link for some examples:
         (if assertion
             (concat "Assertion returned non-nil even on emacs -Q:"
                     bug-hunter--assertion-reminder)
-          "Detected a signaled error even on emacs -Q. I'm sorry, but there
-is something seriously wrong with your Emacs installation.
-There's nothing more I can do here.")
+          "Detected a signaled error even on emacs -Q. This could mean three
+things things:
+1. The problem happens inside `package-initialize'.
+2. You wrote the assertion wrong.
+3. There's something seriously wrong with your Emacs installation.")
         (or assertion "")))
 
      (t
@@ -455,10 +468,17 @@ Wraps them in a progn if necessary to always return a single
 form.
 
 The user may decide to not provide input, in which case
-'interactive is returned.  Note, this is different from the user
-typing `RET' at an empty prompt, in which case nil is returned."
-  (pcase (read-char-choice bug-hunter--hunt-type-prompt '(?i ?e ?a))
-    (`?i 'interactive)
+`interactive' is returned.  Note, this is different from the user
+typing RET at an empty prompt, in which case nil is returned."
+  (pcase (read-char-choice (if (display-graphic-p)
+                               bug-hunter--hunt-type-prompt
+                             (replace-regexp-in-string "To bisect interactively,.*\n" ""
+                                                       bug-hunter--hunt-type-prompt))
+                           '(?i ?e ?a))
+    (`?i
+     (unless (display-graphic-p)
+       (user-error "Sorry, but `interactive' bisection needs a graphical frame"))
+     'interactive)
     (`?e nil)
     (_
      (require 'simple)
@@ -469,7 +489,11 @@ typing `RET' at an empty prompt, in which case nil is returned."
                 (minibuffer-with-setup-hook
                     (lambda ()
                       (add-hook 'completion-at-point-functions
-                                #'elisp-completion-at-point nil t)
+                                (if (fboundp 'elisp-completion-at-point)
+                                    #'elisp-completion-at-point
+                                  (with-no-warnings
+                                    #'lisp-completion-at-point))
+                                nil t)
                       (run-hooks 'eval-expression-minibuffer-setup-hook))
                   (insert
                    (read-from-minibuffer