;;; checkdoc.el --- check documentation strings for style requirements
;; Copyright (C) 1997, 1998, 2001, 2002, 2003, 2004,
-;; 2005, 2006, 2007 Free Software Foundation, Inc.
+;; 2005, 2006, 2007, 2008, 2009 Free Software Foundation, Inc.
;; Author: Eric M. Ludlam <zappo@gnu.org>
;; Version: 0.6.2
;; This file is part of GNU Emacs.
-;; GNU Emacs is free software; you can redistribute it and/or modify
+;; GNU Emacs is free software: you can redistribute it and/or modify
;; it under the terms of the GNU General Public License as published by
-;; the Free Software Foundation; either version 3, or (at your option)
-;; any later version.
+;; the Free Software Foundation, either version 3 of the License, or
+;; (at your option) any later version.
;; GNU Emacs is distributed in the hope that it will be useful,
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
;; GNU General Public License for more details.
;; You should have received a copy of the GNU General Public License
-;; along with GNU Emacs; see the file COPYING. If not, write to the
-;; Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
-;; Boston, MA 02110-1301, USA.
+;; along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>.
;;; Commentary:
;;
(defvar checkdoc-version "0.6.1"
"Release version of checkdoc you are currently running.")
-;; From custom web page for compatibility between versions of custom:
-(eval-and-compile
- (condition-case ()
- (require 'custom)
- (error nil))
- (if (and (featurep 'custom) (fboundp 'custom-declare-variable))
- nil ;; We've got what we needed
- ;; We have the old custom-library, hack around it!
- (defmacro defgroup (&rest args)
- nil)
- (defmacro custom-add-option (&rest args)
- nil)
- (defmacro defcustom (var value doc &rest args)
- `(defvar ,var ,value ,doc))))
+(require 'help-mode) ;; for help-xref-info-regexp
+(require 'thingatpt) ;; for handy thing-at-point-looking-at
(defvar compilation-error-regexp-alist)
(defvar compilation-mode-font-lock-keywords)
:version "20.3")
(defcustom checkdoc-minor-mode-string " CDoc"
- "*String to display in mode line when Checkdoc mode is enabled; nil for none."
+ "String to display in mode line when Checkdoc mode is enabled; nil for none."
:type '(choice string (const :tag "None" nil))
:group 'checkdoc
:version "23.1")
:type 'boolean)
;;;###autoload(put 'checkdoc-force-docstrings-flag 'safe-local-variable 'booleanp)
-(defcustom checkdoc-force-history-flag t
+(defcustom checkdoc-force-history-flag nil
"Non-nil means that files should have a History section or ChangeLog file.
This helps document the evolution of, and recent changes to, the package."
:group 'checkdoc
:type 'boolean)
+;;;###autoload(put 'checkdoc-force-history-flag 'safe-local-variable 'booleanp)
(defcustom checkdoc-permit-comma-termination-flag nil
"Non-nil means the first line of a docstring may end with a comma.
made in the style guide relating to order."
:group 'checkdoc
:type 'boolean)
+;;;###autoload(put 'checkdoc-arguments-in-order-flag 'safe-local-variable 'booleanp)
(defvar checkdoc-style-hooks nil
"Hooks called after the standard style check is completed.
with a universal argument.")
(defcustom checkdoc-symbol-words nil
- "A list of symbols which also happen to make good words.
-These symbol-words are ignored when unquoted symbols are searched for.
+ "A list of symbol names (strings) which also happen to make good words.
+These words are ignored when unquoted symbols are searched for.
This should be set in an Emacs Lisp file's local variables."
:group 'checkdoc
:type '(repeat (symbol :tag "Word")))
+;;;###autoload(put 'checkdoc-symbol-words 'safe-local-variable 'checkdoc-list-of-strings-p)
+
+;;;###autoload
+(defun checkdoc-list-of-strings-p (obj)
+ ;; this is a function so it might be shared by checkdoc-proper-noun-list
+ ;; and/or checkdoc-ispell-lisp-words in the future
+ (and (listp obj)
+ (not (memq nil (mapcar 'stringp obj)))))
(defvar checkdoc-proper-noun-list
'("ispell" "xemacs" "emacs" "lisp")
CHECK is a list of four strings stating the current status of each
test; the nth string describes the status of the nth test."
(let (temp-buffer-setup-hook)
- (with-output-to-temp-buffer " *Checkdoc Status*"
+ (with-output-to-temp-buffer "*Checkdoc Status*"
(princ-list
"Buffer comments and tags: " (nth 0 check) "\n"
"Documentation style: " (nth 1 check) "\n"
"Unwanted Spaces: " (nth 3 check)
)))
(shrink-window-if-larger-than-buffer
- (get-buffer-window " *Checkdoc Status*"))
+ (get-buffer-window "*Checkdoc Status*"))
(message nil)
(sit-for 0))
store all errors found in a warnings buffer,
otherwise stop after the first error."
(interactive "P")
- (if (interactive-p) (message "Checking buffer for style..."))
+ (if (called-interactively-p 'interactive)
+ (message "Checking buffer for style..."))
;; Assign a flag to spellcheck flag
(let ((checkdoc-spellcheck-documentation-flag
(car (memq checkdoc-spellcheck-documentation-flag
(checkdoc-start)
(checkdoc-message-text)
(checkdoc-rogue-spaces)
- (not (interactive-p))
+ (not (called-interactively-p 'interactive))
(if take-notes (checkdoc-show-diagnostics))
(message "Checking buffer for style...Done."))))
(interactive "P")
(let ((p (point)))
(goto-char (point-min))
- (if (and take-notes (interactive-p))
+ (if (and take-notes (called-interactively-p 'interactive))
(checkdoc-start-section "checkdoc-start"))
(checkdoc-continue take-notes)
;; Go back since we can't be here without success above.
(if (not take-notes)
(error "%s" (checkdoc-error-text msg)))))
(checkdoc-show-diagnostics)
- (if (interactive-p)
+ (if (called-interactively-p 'interactive)
(message "No style warnings."))))
(defun checkdoc-next-docstring ()
(e (checkdoc-rogue-space-check-engine nil nil interact))
(checkdoc-generate-compile-warnings-flag
(or take-notes checkdoc-generate-compile-warnings-flag)))
- (if (not (interactive-p))
+ (if (not (called-interactively-p 'interactive))
e
(if e
(message "%s" (checkdoc-error-text e))
(checkdoc-generate-compile-warnings-flag
(or take-notes checkdoc-generate-compile-warnings-flag)))
(setq e (checkdoc-message-text-search))
- (if (not (interactive-p))
+ (if (not (called-interactively-p 'interactive))
e
(if e
(error "%s" (checkdoc-error-text e))
(checkdoc-show-diagnostics)))
(goto-char p))
- (if (interactive-p) (message "Checking interactive message text...done.")))
+ (if (called-interactively-p 'interactive)
+ (message "Checking interactive message text...done.")))
;;;###autoload
(defun checkdoc-eval-defun ()
(if msg (if no-error
(message "%s" (checkdoc-error-text msg))
(error "%s" (checkdoc-error-text msg))))))
- (if (interactive-p) (message "Checkdoc: done."))))))
+ (if (called-interactively-p 'interactive)
+ (message "Checkdoc: done."))))))
;;; Ispell interface for forcing a spell check
;;
map)
"Keymap used to override evaluation key-bindings for documentation checking.")
-(defvaralias 'checkdoc-minor-keymap 'checkdoc-minor-mode-map)
-(make-obsolete-variable 'checkdoc-minor-keymap
- 'checkdoc-minor-mode-map)
+(define-obsolete-variable-alias 'checkdoc-minor-keymap
+ 'checkdoc-minor-mode-map "21.1")
;; Add in a menubar with easy-menu
(checkdoc-create-error
"Flag variable doc strings should usually start: Non-nil means"
s (marker-position e) t))
+ ;; Don't rename variable to "foo-flag". This is unnecessary
+ ;; and such names often end up inconvenient when the variable
+ ;; is later expanded to non-boolean values. --Stef
;; If the doc string starts with "Non-nil means"
- (if (and (looking-at "\"\\*?Non-nil\\s-+means\\s-+")
- (not (string-match "-flag$" (car fp))))
- (let ((newname
- (if (string-match "-p$" (car fp))
- (concat (substring (car fp) 0 -2) "-flag")
- (concat (car fp) "-flag"))))
- (if (checkdoc-y-or-n-p
- (format
- "Rename to %s and Query-Replace all occurrences? "
- newname))
- (progn
- (beginning-of-defun)
- (query-replace-regexp
- (concat "\\<" (regexp-quote (car fp)) "\\>")
- newname))
- (checkdoc-create-error
- "Flag variable names should normally end in `-flag'" s
- (marker-position e)))))
+ ;; (if (and (looking-at "\"\\*?Non-nil\\s-+means\\s-+")
+ ;; (not (string-match "-flag$" (car fp))))
+ ;; (let ((newname
+ ;; (if (string-match "-p$" (car fp))
+ ;; (concat (substring (car fp) 0 -2) "-flag")
+ ;; (concat (car fp) "-flag"))))
+ ;; (if (checkdoc-y-or-n-p
+ ;; (format
+ ;; "Rename to %s and Query-Replace all occurrences? "
+ ;; newname))
+ ;; (progn
+ ;; (beginning-of-defun)
+ ;; (query-replace-regexp
+ ;; (concat "\\<" (regexp-quote (car fp)) "\\>")
+ ;; newname))
+ ;; (checkdoc-create-error
+ ;; "Flag variable names should normally end in `-flag'" s
+ ;; (marker-position e)))))
;; Done with variables
))
(t
checkdoc-common-verbs-wrong-voice))
(if (not rs) (error "Verb voice alist corrupted"))
(setq replace (let ((case-fold-search nil))
- (save-match-data
- (if (string-match "^[A-Z]" original)
- (capitalize (cdr rs))
- (cdr rs)))))
+ (if (string-match-p "^[A-Z]" original)
+ (capitalize (cdr rs))
+ (cdr rs))))
(if (checkdoc-autofix-ask-replace
(match-beginning 1) (match-end 1)
(format "Use the imperative for \"%s\". \
"[^-([`':a-zA-Z]\\(\\w+[:-]\\(\\w\\|\\s_\\)+\\)[^]']"
e t))
(setq ms (match-string 1))
- (save-match-data
- ;; A . is a \s_ char, so we must remove periods from
- ;; sentences more carefully.
- (if (string-match "\\.$" ms)
- (setq ms (substring ms 0 (1- (length ms))))))
+ ;; A . is a \s_ char, so we must remove periods from
+ ;; sentences more carefully.
+ (when (string-match-p "\\.$" ms)
+ (setq ms (substring ms 0 (1- (length ms)))))
(if (and (not (checkdoc-in-sample-code-p start e))
(not (checkdoc-in-example-string-p start e))
(not (member ms checkdoc-symbol-words))
;; surrounded by /, as in a URL or filename: /emacs/
(not (and (= ?/ (char-after e))
(= ?/ (char-before b))))
- (not (checkdoc-in-example-string-p begin end)))
+ (not (checkdoc-in-example-string-p begin end))
+ ;; info or url links left alone
+ (not (thing-at-point-looking-at
+ help-xref-info-regexp))
+ (not (thing-at-point-looking-at
+ help-xref-url-regexp)))
(if (checkdoc-autofix-ask-replace
b e (format "Text %s should be capitalized. Fix? "
text)
(progn
(forward-sexp -1)
;; piece of an abbreviation
+ ;; FIXME etc
(looking-at
"\\([a-z]\\|[iI]\\.?e\\|[eE]\\.?g\\)\\."))
(error t))))
;; b) determine if we have lm-history symbol which doesn't always exist
(require 'lisp-mnt))
+(defvar generate-autoload-cookie)
+
(defun checkdoc-file-comments-engine ()
"Return a message list if this file does not match the Emacs standard.
This checks for style only, such as the first line, Commentary:,
(or
;; * Code section
(if (not (lm-code-mark))
- (let ((cont t))
+ (let ((cont t)
+ pos)
(goto-char (point-min))
- (while (and cont (re-search-forward "^(" nil t))
- (setq cont (looking-at "require\\s-+")))
+ ;; match ";;;###autoload" cookie to keep it with the form
+ (require 'autoload)
+ (while (and cont (re-search-forward
+ (concat "^\\("
+ (regexp-quote generate-autoload-cookie)
+ "\n\\)?"
+ "(")
+ nil t))
+ (setq pos (match-beginning 0)
+ cont (looking-at "require\\s-+")))
(if (and (not cont)
(checkdoc-y-or-n-p
"There is no ;;; Code: marker. Insert one? "))
- (progn (beginning-of-line)
- (insert ";;; Code:\n")
+ (progn (goto-char pos)
+ (insert ";;; Code:\n\n")
nil)
(checkdoc-create-error
"You should have a section marked \";;; Code:\""
(checkdoc-output-mode)
(setq default-directory dir)
(goto-char (point-max))
- (insert "\n\n\C-l\n*** " label ": " check-type " V " checkdoc-version))))
+ (let ((inhibit-read-only t))
+ (insert "\n\n\C-l\n*** " label ": "
+ check-type " V " checkdoc-version)))))
(defun checkdoc-error (point msg)
"Store POINT and MSG as errors in the checkdoc diagnostic buffer."
": " msg)))
(with-current-buffer (get-buffer checkdoc-diagnostic-buffer)
(goto-char (point-max))
- (apply 'insert text))))
+ (let ((inhibit-read-only t))
+ (apply 'insert text)))))
(defun checkdoc-show-diagnostics ()
"Display the checkdoc diagnostic buffer in a temporary window."