From 55083d90a30628d9eaa5b94196291ca15098aed0 Mon Sep 17 00:00:00 2001 From: Stefan Kangas Date: Thu, 23 Sep 2021 21:10:08 +0200 Subject: [PATCH] Avoid jumping too far in checkdoc-in-abbreviation-p * lisp/emacs-lisp/checkdoc.el (checkdoc-in-abbreviation-p): Use 'forward-ward' instead of 'forward-sexp' to avoid jumping too far in some situations. (Bug#50731) * test/lisp/emacs-lisp/checkdoc-tests.el (checkdoc-tests--abbrev-test): New helper function. (checkdoc-tests-in-abbrevation-p/basic-case): Rename from 'checkdoc-tests-in-abbrevation-p'. (checkdoc-tests-in-abbrevation-p/with-parens) (checkdoc-tests-in-abbrevation-p/with-escaped-parens): Use above new helper function. (checkdoc-tests-in-abbrevation-p/single-char) (checkdoc-tests-in-abbrevation-p/with-em-dash) (checkdoc-tests-in-abbrevation-p/incorrect-abbreviation): New tests. --- lisp/emacs-lisp/checkdoc.el | 42 ++++++++++++++------------ test/lisp/emacs-lisp/checkdoc-tests.el | 34 +++++++++++---------- 2 files changed, 41 insertions(+), 35 deletions(-) diff --git a/lisp/emacs-lisp/checkdoc.el b/lisp/emacs-lisp/checkdoc.el index 5224a943ac0..4243e828001 100644 --- a/lisp/emacs-lisp/checkdoc.el +++ b/lisp/emacs-lisp/checkdoc.el @@ -2097,27 +2097,31 @@ Examples of abbreviations handled: \"e.g.\", \"i.e.\", \"cf.\"." (save-excursion (goto-char begin) (condition-case nil - (progn - (forward-sexp -1) + (let ((single-letter t)) + (forward-word -1) + ;; Skip over all dots backwards, as `forward-word' will only + ;; go one dot at a time in a string like "e.g.". + (while (save-excursion (forward-char -1) + (looking-at (rx "."))) + (setq single-letter nil) + (forward-word -1)) ;; Piece of an abbreviation. (looking-at - (rx (or letter ; single letter, as in "a." - (seq - ;; There might exist an escaped parenthesis, as - ;; this is often used in docstrings. In this - ;; case, `forward-sexp' will have skipped over it, - ;; so we need to skip it here too. - (? "\\(") - ;; The abbreviations: - (or (seq (any "cC") "f") ; cf. - (seq (any "eE") ".g") ; e.g. - (seq (any "iI") "." (any "eE")))) ; i.e. - "etc" ; etc. - "vs" ; vs. - ;; Some non-standard or less common ones that we - ;; might as well ignore. - "Inc" "Univ" "misc" "resp") - "."))) + (if single-letter + ;; Handle a single letter, as in "a.", as this might be + ;; a part of a list. + (rx letter ".") + (rx (or + ;; The abbreviations: + (seq (or (seq (any "cC") "f") ; cf. + (seq (any "eE") ".g") ; e.g. + (seq (any "iI") "." (any "eE")))) ; i.e. + "etc" ; etc. + "vs" ; vs. + ;; Some non-standard or less common ones that we + ;; might as well ignore. + "Inc" "Univ" "misc" "resp") + ".")))) (error t)))) (defun checkdoc-proper-noun-region-engine (begin end) diff --git a/test/lisp/emacs-lisp/checkdoc-tests.el b/test/lisp/emacs-lisp/checkdoc-tests.el index 3eb7da3d4a7..13b6d134e5c 100644 --- a/test/lisp/emacs-lisp/checkdoc-tests.el +++ b/test/lisp/emacs-lisp/checkdoc-tests.el @@ -122,29 +122,31 @@ See the comments in Bug#24998." (should (looking-at-p "\"baz\")")) (should-not (checkdoc-next-docstring)))) -(ert-deftest checkdoc-tests-in-abbrevation-p () +(defun checkdoc-tests--abbrev-test (buffer-contents goto-string) (with-temp-buffer (emacs-lisp-mode) - (insert "foo bar e.g. baz") + (insert buffer-contents) (goto-char (point-min)) - (re-search-forward "e.g") - (should (checkdoc-in-abbreviation-p (point))))) + (re-search-forward goto-string) + (checkdoc-in-abbreviation-p (point)))) + +(ert-deftest checkdoc-tests-in-abbrevation-p/basic-case () + (should (checkdoc-tests--abbrev-test "foo bar e.g. baz" "e.g"))) (ert-deftest checkdoc-tests-in-abbrevation-p/with-parens () - (with-temp-buffer - (emacs-lisp-mode) - (insert "foo bar (e.g. baz)") - (goto-char (point-min)) - (re-search-forward "e.g") - (should (checkdoc-in-abbreviation-p (point))))) + (should (checkdoc-tests--abbrev-test "foo bar (e.g. baz)" "e.g"))) (ert-deftest checkdoc-tests-in-abbrevation-p/with-escaped-parens () - (with-temp-buffer - (emacs-lisp-mode) - (insert "foo\n\\(e.g. baz)") - (goto-char (point-min)) - (re-search-forward "e.g") - (should (checkdoc-in-abbreviation-p (point))))) + (should (checkdoc-tests--abbrev-test "foo\n\\(e.g. baz)" "e.g"))) + +(ert-deftest checkdoc-tests-in-abbrevation-p/single-char () + (should (checkdoc-tests--abbrev-test "a. foo bar" "a"))) + +(ert-deftest checkdoc-tests-in-abbrevation-p/with-em-dash () + (should (checkdoc-tests--abbrev-test "foo bar baz---e.g." "e.g"))) + +(ert-deftest checkdoc-tests-in-abbrevation-p/incorrect-abbreviation () + (should-not (checkdoc-tests--abbrev-test "foo bar a.b.c." "a.b.c"))) (ert-deftest checkdoc-tests-fix-y-or-n-p () (with-temp-buffer -- 2.39.2