]> git.eshelyaron.com Git - emacs.git/commitdiff
checkdoc: Allow Lisp symbols to start a message
authorStefan Kangas <stefan@marxist.se>
Sat, 25 Sep 2021 23:20:55 +0000 (01:20 +0200)
committerStefan Kangas <stefan@marxist.se>
Mon, 27 Sep 2021 23:12:36 +0000 (01:12 +0200)
* lisp/emacs-lisp/checkdoc.el (checkdoc-message-text-engine): Allow
Lisp symbols to start a message.
(checkdoc--error-bad-format-p): New helper function.

* test/lisp/emacs-lisp/checkdoc-tests.el
(checkdoc-test-error-format-is-good)
(checkdoc-test-error-format-is-bad): New helper functions.
(checkdoc-tests-error-message-bad-format-p)
(checkdoc-tests-error-message-bad-format-p/defined-symbols)
(checkdoc-tests-error-message-bad-format-p/not-capitalized):
New tests.

lisp/emacs-lisp/checkdoc.el
test/lisp/emacs-lisp/checkdoc-tests.el

index b3707bb7863fd7a217f10dda6eb3d39d19bb9502..5ea2f59ee60c7f5943f99c3882cd664dc139b83f 100644 (file)
 (require 'cl-lib)
 (require 'help-mode) ;; for help-xref-info-regexp
 (require 'thingatpt) ;; for handy thing-at-point-looking-at
+(require 'lisp-mode) ;; for lisp-mode-symbol-regexp
 (require 'dired)     ;; for dired-get-filename and dired-map-over-marks
 (require 'lisp-mnt)
 
@@ -2575,6 +2576,30 @@ Argument END is the maximum bounds to search in."
          (setq return type))))
     return))
 
+(defun checkdoc--error-bad-format-p ()
+  "Return non-nil if the start of error message at point has the wrong format.
+The correct format is \"Foo\" or \"some-symbol: Foo\".  See also
+`error' and Info node `(elisp) Documentation Tips'."
+  (save-excursion
+    ;; Skip the first quote character in string.
+    (forward-char 1)
+    ;; A capital letter is always okay.
+    (unless (let ((case-fold-search nil))
+              (looking-at (rx (or upper-case "%s"))))
+      ;; A defined Lisp symbol is always okay.
+      (unless (and (looking-at (rx (group (regexp lisp-mode-symbol-regexp))))
+                   (or (fboundp (intern (match-string 1)))
+                       (boundp (intern (match-string 1)))))
+        ;; Other Lisp symbols are sometimes okay.
+        (rx-let ((c (? "\\\n")))        ; `c' is for a continued line
+          (let ((case-fold-search nil)
+                (some-symbol (rx (regexp lisp-mode-symbol-regexp)
+                                 c ":" c (+ (any " \t\n"))))
+                (lowercase-str (rx c (group (any "a-z") (+ wordchar)))))
+            (if (looking-at some-symbol)
+                (looking-at (concat some-symbol lowercase-str))
+              (looking-at lowercase-str))))))))
+
 (defun checkdoc--fix-y-or-n-p ()
   "Fix `y-or-n-p' prompt to end with \"?\" or \"? \".
 The space is technically redundant, but also more compatible with
@@ -2622,16 +2647,14 @@ Argument TYPE specifies the type of question, such as `error' or `y-or-n-p'."
      ;; In Emacs, the convention is that error messages start with a capital
      ;; letter but *do not* end with a period.  Please follow this convention
      ;; for the sake of consistency.
-     (if (and (save-excursion (forward-char 1)
-                             (looking-at "[a-z]\\w+"))
+     (if (and (checkdoc--error-bad-format-p)
              (not (checkdoc-autofix-ask-replace
-                   (match-beginning 0) (match-end 0)
+                    (match-beginning 1) (match-end 1)
                     "Capitalize your message text?"
-                   (capitalize (match-string 0))
+                    (capitalize (match-string 1))
                    t)))
-        (checkdoc-create-error
-         "Messages should start with a capital letter"
-         (match-beginning 0) (match-end 0))
+         (checkdoc-create-error "Messages should start with a capital letter"
+          (match-beginning 1) (match-end 1))
        nil)
      ;; In general, sentences should have two spaces after the period.
      (checkdoc-sentencespace-region-engine (point)
index d452024b8ff8ff852378d8cd55a8b2f2b1e6706e..ef49e71599a9b1a7e806e61387d8cd5319672c37 100644 (file)
@@ -151,6 +151,43 @@ See the comments in Bug#24998."
 (ert-deftest checkdoc-tests-in-abbrevation-p/incorrect-abbreviation ()
   (should-not (checkdoc-tests--abbrev-test "foo bar a.b.c." "a.b.c")))
 
+(defun checkdoc-test-error-format-is-good (msg &optional reverse literal)
+  (with-temp-buffer
+    (erase-buffer)
+    (emacs-lisp-mode)
+    (let ((standard-output (current-buffer)))
+      (if literal
+          (print (format "(error \"%s\")" msg))
+        (prin1 `(error ,msg))))
+    (goto-char (length "(error \""))
+    (if reverse
+         (should (checkdoc--error-bad-format-p))
+       (should-not (checkdoc--error-bad-format-p)))))
+
+(defun checkdoc-test-error-format-is-bad (msg &optional literal)
+  (checkdoc-test-error-format-is-good msg t literal))
+
+(ert-deftest checkdoc-tests-error-message-bad-format-p ()
+  (checkdoc-test-error-format-is-good "Foo")
+  (checkdoc-test-error-format-is-good "Foo: bar baz")
+  (checkdoc-test-error-format-is-good "some-symbol: Foo")
+  (checkdoc-test-error-format-is-good "`some-symbol' foo bar")
+  (checkdoc-test-error-format-is-good "%sfoo")
+  (checkdoc-test-error-format-is-good "avl-tree-enter:\\
+ Updated data does not match existing data" nil 'literal))
+
+(ert-deftest checkdoc-tests-error-message-bad-format-p/defined-symbols ()
+  (defvar checkdoc-tests--var-symbol nil)
+  (checkdoc-test-error-format-is-good "checkdoc-tests--var-symbol foo bar baz")
+  (defun checkdoc-tests--fun-symbol ())
+  (checkdoc-test-error-format-is-good "checkdoc-tests--fun-symbol foo bar baz"))
+
+(ert-deftest checkdoc-tests-error-message-bad-format-p/not-capitalized ()
+  (checkdoc-test-error-format-is-bad "foo")
+  (checkdoc-test-error-format-is-bad "some-symbol: foo")
+  (checkdoc-test-error-format-is-bad "avl-tree-enter:\
+ updated data does not match existing data"))
+
 (ert-deftest checkdoc-tests-fix-y-or-n-p ()
   (with-temp-buffer
     (emacs-lisp-mode)