checkdoc: Allow Lisp symbols to start a message

* 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.
This commit is contained in:
Stefan Kangas 2021-09-26 01:20:55 +02:00
parent 6bec21243d
commit 3cabf64131
2 changed files with 67 additions and 7 deletions

View file

@ -164,6 +164,7 @@
(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)

View 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)