(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)
(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
;; 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)
(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)