Mercurial > emacs
comparison lisp/emacs-lisp/elint.el @ 104049:7fcfa9c429bd
(elint-current-buffer, elint-defun):
Add autoload cookies. If necessary, initialize.
(elint-log): Handle non-file buffers.
(elint-initialize): Add optional argument to reinitialize.
(elint-find-builtin-variables): Save excursion.
author | Glenn Morris <rgm@gnu.org> |
---|---|
date | Fri, 24 Jul 2009 03:52:42 +0000 |
parents | 1a42628a650e |
children | 646ba543ede9 |
comparison
equal
deleted
inserted
replaced
104048:712697e0dfcc | 104049:7fcfa9c429bd |
---|---|
26 | 26 |
27 ;; This is a linter for Emacs Lisp. Currently, it mainly catches | 27 ;; This is a linter for Emacs Lisp. Currently, it mainly catches |
28 ;; misspellings and undefined variables, although it can also catch | 28 ;; misspellings and undefined variables, although it can also catch |
29 ;; function calls with the wrong number of arguments. | 29 ;; function calls with the wrong number of arguments. |
30 | 30 |
31 ;; Before using, call `elint-initialize' to set up some argument | 31 ;; To use, call elint-current-buffer or elint-defun to lint a buffer |
32 ;; data. This takes a while. Then call elint-current-buffer or | 32 ;; or defun. The first call runs `elint-initialize' to set up some |
33 ;; elint-defun to lint a buffer or a defun. | 33 ;; argument data, which may take a while. |
34 | 34 |
35 ;; The linter will try to "include" any require'd libraries to find | 35 ;; The linter will try to "include" any require'd libraries to find |
36 ;; the variables defined in those. There is a fair amount of voodoo | 36 ;; the variables defined in those. There is a fair amount of voodoo |
37 ;; involved in this, but it seems to work in normal situations. | 37 ;; involved in this, but it seems to work in normal situations. |
38 | 38 |
149 | 149 |
150 ;;; | 150 ;;; |
151 ;;; User interface | 151 ;;; User interface |
152 ;;; | 152 ;;; |
153 | 153 |
154 ;;;###autoload | |
154 (defun elint-current-buffer () | 155 (defun elint-current-buffer () |
155 "Lint the current buffer." | 156 "Lint the current buffer. |
157 If necessary, this first calls `elint-initalize'." | |
156 (interactive) | 158 (interactive) |
159 (or elint-builtin-variables | |
160 (elint-initialize)) | |
157 (elint-clear-log (format "Linting %s" (or (buffer-file-name) | 161 (elint-clear-log (format "Linting %s" (or (buffer-file-name) |
158 (buffer-name)))) | 162 (buffer-name)))) |
159 (elint-display-log) | 163 (elint-display-log) |
160 (mapc 'elint-top-form (elint-update-env)) | 164 (mapc 'elint-top-form (elint-update-env)) |
161 ;; Tell the user we're finished. This is terribly klugy: we set | 165 ;; Tell the user we're finished. This is terribly klugy: we set |
162 ;; elint-top-form-logged so elint-log-message doesn't print the | 166 ;; elint-top-form-logged so elint-log-message doesn't print the |
163 ;; ** top form ** header... | 167 ;; ** top form ** header... |
164 (let ((elint-top-form-logged t)) | 168 (let ((elint-top-form-logged t)) |
165 (elint-log-message "\nLinting finished.\n"))) | 169 (elint-log-message "\nLinting finished.\n"))) |
166 | 170 |
171 ;;;###autoload | |
167 (defun elint-defun () | 172 (defun elint-defun () |
168 "Lint the function at point." | 173 "Lint the function at point. |
174 If necessary, this first calls `elint-initalize'." | |
169 (interactive) | 175 (interactive) |
176 (or elint-builtin-variables | |
177 (elint-initialize)) | |
170 (save-excursion | 178 (save-excursion |
171 (or (beginning-of-defun) (error "Lint what?")) | 179 (or (beginning-of-defun) (error "Lint what?")) |
172 (let ((pos (point)) | 180 (let ((pos (point)) |
173 (def (read (current-buffer)))) | 181 (def (read (current-buffer)))) |
174 (elint-display-log) | 182 (elint-display-log) |
608 | 616 |
609 (defvar elint-current-pos) ; dynamically bound in elint-top-form | 617 (defvar elint-current-pos) ; dynamically bound in elint-top-form |
610 | 618 |
611 (defun elint-log (type string args) | 619 (defun elint-log (type string args) |
612 (elint-log-message (format "%s:%d:%s: %s" | 620 (elint-log-message (format "%s:%d:%s: %s" |
613 (file-name-nondirectory (buffer-file-name)) | 621 (let ((f (buffer-file-name))) |
622 (if f | |
623 (file-name-nondirectory f) | |
624 (buffer-name))) | |
614 (save-excursion | 625 (save-excursion |
615 (goto-char elint-current-pos) | 626 (goto-char elint-current-pos) |
616 (1+ (count-lines (point-min) | 627 (1+ (count-lines (point-min) |
617 (line-beginning-position)))) | 628 (line-beginning-position)))) |
618 type | 629 type |
678 ;;; | 689 ;;; |
679 ;;; Initializing code | 690 ;;; Initializing code |
680 ;;; | 691 ;;; |
681 | 692 |
682 ;;;###autoload | 693 ;;;###autoload |
683 (defun elint-initialize () | 694 (defun elint-initialize (&optional reinit) |
684 "Initialize elint." | 695 "Initialize elint. |
685 (interactive) | 696 If elint is already initialized, this does nothing, unless |
686 (setq elint-builtin-variables (elint-find-builtin-variables) | 697 optional prefix argument REINIT is non-nil." |
687 elint-autoloaded-variables (elint-find-autoloaded-variables)) | 698 (interactive "P") |
688 (mapc (lambda (x) (or (not (symbolp (car x))) | 699 (if (and elint-builtin-variables (not reinit)) |
689 (eq (cdr x) 'unknown) | 700 (message "Elint is already initialized") |
690 (put (car x) 'elint-args (cdr x)))) | 701 (message "Initializing elint...") |
691 (elint-find-builtin-args)) | 702 (setq elint-builtin-variables (elint-find-builtin-variables) |
692 (if elint-unknown-builtin-args | 703 elint-autoloaded-variables (elint-find-autoloaded-variables)) |
693 (mapc (lambda (x) (put (car x) 'elint-args (cdr x))) | 704 (mapc (lambda (x) (or (not (symbolp (car x))) |
694 elint-unknown-builtin-args))) | 705 (eq (cdr x) 'unknown) |
706 (put (car x) 'elint-args (cdr x)))) | |
707 (elint-find-builtin-args)) | |
708 (if elint-unknown-builtin-args | |
709 (mapc (lambda (x) (put (car x) 'elint-args (cdr x))) | |
710 elint-unknown-builtin-args)) | |
711 (message "Initializing elint...done"))) | |
695 | 712 |
696 | 713 |
697 (defun elint-find-builtin-variables () | 714 (defun elint-find-builtin-variables () |
698 "Return a list of all built-in variables." | 715 "Return a list of all built-in variables." |
699 ;; Cribbed from help-fns.el. | 716 ;; Cribbed from help-fns.el. |
700 (let ((docbuf " *DOC*") | 717 (let ((docbuf " *DOC*") |
701 vars var) | 718 vars var) |
702 (if (get-buffer docbuf) | 719 (save-excursion |
703 (progn | 720 (if (get-buffer docbuf) |
704 (set-buffer docbuf) | 721 (progn |
705 (goto-char (point-min))) | 722 (set-buffer docbuf) |
706 (set-buffer (get-buffer-create docbuf)) | 723 (goto-char (point-min))) |
707 (insert-file-contents-literally | 724 (set-buffer (get-buffer-create docbuf)) |
708 (expand-file-name internal-doc-file-name doc-directory))) | 725 (insert-file-contents-literally |
709 (while (search-forward "V" nil t) | 726 (expand-file-name internal-doc-file-name doc-directory))) |
710 (and (setq var (intern-soft | 727 (while (search-forward "V" nil t) |
711 (buffer-substring (point) (line-end-position)))) | 728 (and (setq var (intern-soft |
712 (boundp var) | 729 (buffer-substring (point) (line-end-position)))) |
713 (setq vars (cons var vars)))) | 730 (boundp var) |
714 vars)) | 731 (setq vars (cons var vars)))) |
732 vars))) | |
715 | 733 |
716 (defun elint-find-autoloaded-variables () | 734 (defun elint-find-autoloaded-variables () |
717 "Return a list of all autoloaded variables." | 735 "Return a list of all autoloaded variables." |
718 (let (var vars) | 736 (let (var vars) |
719 (with-temp-buffer | 737 (with-temp-buffer |