Integrate Flymake elisp checkers into elisp-mode.el directly
* lisp/progmodes/elisp-mode.el (emacs-lisp-mode): Use elisp-flymake-checkdoc and elisp-flymake-byte-compile. (elisp-flymake--checkdoc-1, elisp-flymake-checkdoc) (elisp-flymake--byte-compile-done) (elisp-flymake--byte-compile-process) (elisp-flymake-byte-compile): Rename from flymake-elisp counterparts in deleted flymake-elisp.el (elisp-flymake--batch-compile-for-flymake): New helper. (checkdoc-create-error-function) (checkdoc-autofix-flag) (checkdoc-generate-compile-warnings-flag) (checkdoc-diagnostic-buffer): Forward declare. * lisp/progmodes/flymake-elisp.el: Delete.
This commit is contained in:
parent
30ea272fe4
commit
602d9376db
2 changed files with 165 additions and 190 deletions
|
@ -244,8 +244,8 @@ Blank lines separate paragraphs. Semicolons start comments.
|
|||
(setq-local project-vc-external-roots-function #'elisp-load-path-roots)
|
||||
(add-hook 'completion-at-point-functions
|
||||
#'elisp-completion-at-point nil 'local)
|
||||
(add-hook 'flymake-diagnostic-functions #'flymake-elisp-checkdoc nil t)
|
||||
(add-hook 'flymake-diagnostic-functions #'flymake-elisp-byte-compile nil t))
|
||||
(add-hook 'flymake-diagnostic-functions #'elisp-flymake-checkdoc nil t)
|
||||
(add-hook 'flymake-diagnostic-functions #'elisp-flymake-byte-compile nil t))
|
||||
|
||||
;; Font-locking support.
|
||||
|
||||
|
@ -812,7 +812,7 @@ non-nil result supercedes the xrefs produced by
|
|||
(apply #'nconc
|
||||
(let (lst)
|
||||
(dolist (sym (apropos-internal regexp))
|
||||
(push (elisp--xref-find-definitions sym) lst))
|
||||
(push (elisp--xref-find-definitions sym) lst))
|
||||
(nreverse lst))))
|
||||
|
||||
(defvar elisp--xref-identifier-completion-table
|
||||
|
@ -1111,7 +1111,7 @@ If CHAR is not a character, return nil."
|
|||
;; interactive call would use it.
|
||||
;; FIXME: Is it really the right place for this?
|
||||
(when (eq (car-safe expr) 'interactive)
|
||||
(setq expr
|
||||
(setq expr
|
||||
`(call-interactively
|
||||
(lambda (&rest args) ,expr args))))
|
||||
expr)))))
|
||||
|
@ -1176,7 +1176,7 @@ POS specifies the starting position where EXP was found and defaults to point."
|
|||
(and (not (special-variable-p var))
|
||||
(save-excursion
|
||||
(zerop (car (syntax-ppss (match-beginning 0)))))
|
||||
(push var vars))))
|
||||
(push var vars))))
|
||||
`(progn ,@(mapcar (lambda (v) `(defvar ,v)) vars) ,exp)))))
|
||||
|
||||
(defun eval-last-sexp (eval-last-sexp-arg-internal)
|
||||
|
@ -1381,7 +1381,7 @@ or elsewhere, return a 1-line docstring."
|
|||
(t (help-function-arglist sym)))))
|
||||
;; Stringify, and store before highlighting, downcasing, etc.
|
||||
(elisp--last-data-store sym (elisp-function-argstring args)
|
||||
'function))))))
|
||||
'function))))))
|
||||
;; Highlight, truncate.
|
||||
(if argstring
|
||||
(elisp--highlight-function-argument
|
||||
|
@ -1590,5 +1590,164 @@ ARGLIST is either a string, or a list of strings or symbols."
|
|||
(replace-match "(" t t str)
|
||||
str)))
|
||||
|
||||
;;; Flymake support
|
||||
|
||||
;; Don't require checkdoc, but forward declare these checkdoc special
|
||||
;; variables. Autoloading them on `checkdoc-current-buffer' is too
|
||||
;; late, they won't be bound dynamically.
|
||||
(defvar checkdoc-create-error-function)
|
||||
(defvar checkdoc-autofix-flag)
|
||||
(defvar checkdoc-generate-compile-warnings-flag)
|
||||
(defvar checkdoc-diagnostic-buffer)
|
||||
(defun elisp-flymake--checkdoc-1 ()
|
||||
"Do actual work for `elisp-flymake-checkdoc'."
|
||||
(let (collected)
|
||||
(let* ((checkdoc-create-error-function
|
||||
(lambda (text start end &optional unfixable)
|
||||
(push (list text start end unfixable) collected)
|
||||
nil))
|
||||
(checkdoc-autofix-flag nil)
|
||||
(checkdoc-generate-compile-warnings-flag nil)
|
||||
(buf (generate-new-buffer " *checkdoc-temp*"))
|
||||
(checkdoc-diagnostic-buffer buf))
|
||||
(unwind-protect
|
||||
(save-excursion
|
||||
(checkdoc-current-buffer t))
|
||||
(kill-buffer buf)))
|
||||
collected))
|
||||
|
||||
;;;###autoload
|
||||
(defun elisp-flymake-checkdoc (report-fn)
|
||||
"A Flymake backend for `checkdoc'.
|
||||
Calls REPORT-FN directly."
|
||||
(unless (derived-mode-p 'emacs-lisp-mode)
|
||||
(error "Can only work on `emacs-lisp-mode' buffers"))
|
||||
(funcall report-fn
|
||||
(cl-loop for (text start end _unfixable) in
|
||||
(elisp-flymake--checkdoc-1)
|
||||
collect
|
||||
(flymake-make-diagnostic
|
||||
(current-buffer)
|
||||
start end :note text))))
|
||||
|
||||
(defun elisp-flymake--byte-compile-done (report-fn
|
||||
origin-buffer
|
||||
output-buffer
|
||||
temp-file)
|
||||
(unwind-protect
|
||||
(with-current-buffer
|
||||
origin-buffer
|
||||
(save-excursion
|
||||
(save-restriction
|
||||
(widen)
|
||||
(funcall
|
||||
report-fn
|
||||
(cl-loop with data =
|
||||
(with-current-buffer output-buffer
|
||||
(goto-char (point-min))
|
||||
(search-forward ":elisp-flymake-output-start")
|
||||
(read (point-marker)))
|
||||
for (string pos _fill level) in data
|
||||
do (goto-char pos)
|
||||
for beg = (if (< (point) (point-max))
|
||||
(point)
|
||||
(line-beginning-position))
|
||||
for end = (min
|
||||
(line-end-position)
|
||||
(or (cdr
|
||||
(bounds-of-thing-at-point 'sexp))
|
||||
(point-max)))
|
||||
collect (flymake-make-diagnostic
|
||||
(current-buffer)
|
||||
(if (= beg end) (1- beg) beg)
|
||||
end
|
||||
level
|
||||
string))))))
|
||||
(kill-buffer output-buffer)
|
||||
(ignore-errors (delete-file temp-file))))
|
||||
|
||||
(defvar-local elisp-flymake--byte-compile-process nil
|
||||
"Buffer-local process started for byte-compiling the buffer.")
|
||||
|
||||
;;;###autoload
|
||||
(defun elisp-flymake-byte-compile (report-fn)
|
||||
"A Flymake backend for elisp byte compilation.
|
||||
Spawn an Emacs process that byte-compiles a file representing the
|
||||
current buffer state and calls REPORT-FN when done."
|
||||
(interactive (list (lambda (stuff)
|
||||
(message "aha %s" stuff))))
|
||||
(unless (derived-mode-p 'emacs-lisp-mode)
|
||||
(error "Can only work on `emacs-lisp-mode' buffers"))
|
||||
(when elisp-flymake--byte-compile-process
|
||||
(process-put elisp-flymake--byte-compile-process 'elisp-flymake--obsolete t)
|
||||
(when (process-live-p elisp-flymake--byte-compile-process)
|
||||
(kill-process elisp-flymake--byte-compile-process)))
|
||||
(let ((temp-file (make-temp-file "elisp-flymake-byte-compile"))
|
||||
(origin-buffer (current-buffer)))
|
||||
(save-restriction
|
||||
(widen)
|
||||
(write-region (point-min) (point-max) temp-file nil 'nomessage))
|
||||
(let* ((output-buffer (generate-new-buffer " *elisp-flymake-byte-compile*")))
|
||||
(setq
|
||||
elisp-flymake--byte-compile-process
|
||||
(make-process
|
||||
:name "elisp-flymake-byte-compile"
|
||||
:buffer output-buffer
|
||||
:command (list (expand-file-name invocation-name invocation-directory)
|
||||
"-Q"
|
||||
"--batch"
|
||||
;; "--eval" "(setq load-prefer-newer t)" ; for testing
|
||||
"-L" default-directory
|
||||
"-f" "elisp-flymake--batch-compile-for-flymake"
|
||||
temp-file)
|
||||
:connection-type 'pipe
|
||||
:sentinel
|
||||
(lambda (proc _event)
|
||||
(unless (process-live-p proc)
|
||||
(unwind-protect
|
||||
(cond
|
||||
((zerop (process-exit-status proc))
|
||||
(elisp-flymake--byte-compile-done report-fn
|
||||
origin-buffer
|
||||
output-buffer
|
||||
temp-file))
|
||||
((process-get proc 'elisp-flymake--obsolete)
|
||||
(flymake-log :warning "byte-compile process %s obsolete" proc))
|
||||
(t
|
||||
(funcall report-fn
|
||||
:panic
|
||||
:explanation
|
||||
(format "byte-compile process %s died" proc)))))))))
|
||||
:stderr null-device
|
||||
:noquery t)))
|
||||
|
||||
(defun elisp-flymake--batch-compile-for-flymake (&optional file)
|
||||
"Helper for `elisp-flymake-byte-compile'.
|
||||
Runs in a batch-mode Emacs. Interactively use variable
|
||||
`buffer-file-name' for FILE."
|
||||
(interactive (list buffer-file-name))
|
||||
(let* ((file (or file
|
||||
(car command-line-args-left)))
|
||||
(dummy-elc-file)
|
||||
(byte-compile-log-buffer
|
||||
(generate-new-buffer " *dummy-byte-compile-log-buffer*"))
|
||||
(byte-compile-dest-file-function
|
||||
(lambda (source)
|
||||
(setq dummy-elc-file (make-temp-file (file-name-nondirectory source)))))
|
||||
(collected)
|
||||
(byte-compile-log-warning-function
|
||||
(lambda (string &optional position fill level)
|
||||
(push (list string position fill level)
|
||||
collected)
|
||||
t)))
|
||||
(unwind-protect
|
||||
(byte-compile-file file)
|
||||
(ignore-errors
|
||||
(delete-file dummy-elc-file)
|
||||
(kill-buffer byte-compile-log-buffer)))
|
||||
(prin1 :elisp-flymake-output-start)
|
||||
(terpri)
|
||||
(pp collected)))
|
||||
|
||||
(provide 'elisp-mode)
|
||||
;;; elisp-mode.el ends here
|
||||
|
|
|
@ -1,184 +0,0 @@
|
|||
;;; flymake-elisp.el --- Flymake backends for emacs-lisp-mode -*- lexical-binding: t; -*-
|
||||
|
||||
;; Copyright (C) 2003-2017 Free Software Foundation, Inc.
|
||||
|
||||
;; Author: João Távora <joaotavora@gmail.com>
|
||||
;; Keywords: languages tools
|
||||
|
||||
;; This program 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 of the License, or
|
||||
;; (at your option) any later version.
|
||||
|
||||
;; This program is distributed in the hope that it will be useful,
|
||||
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
;; GNU General Public License for more details.
|
||||
|
||||
;; You should have received a copy of the GNU General Public License
|
||||
;; along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
;;; Commentary:
|
||||
|
||||
;; Flymake backends for elisp work, `flymake-elisp-checkdoc' and
|
||||
;; `flymake-elisp-byte-compile'.
|
||||
|
||||
;;; Code:
|
||||
(require 'flymake)
|
||||
(require 'checkdoc)
|
||||
(eval-when-compile (require 'cl-lib))
|
||||
(require 'bytecomp)
|
||||
|
||||
(defun flymake-elisp--checkdoc-1 ()
|
||||
"Do actual work for `flymake-elisp-checkdoc'."
|
||||
(let (collected)
|
||||
(let* ((checkdoc-create-error-function
|
||||
(lambda (text start end &optional unfixable)
|
||||
(push (list text start end unfixable) collected)
|
||||
nil))
|
||||
(checkdoc-autofix-flag nil)
|
||||
(checkdoc-generate-compile-warnings-flag nil)
|
||||
(buf (generate-new-buffer " *checkdoc-temp*"))
|
||||
(checkdoc-diagnostic-buffer buf))
|
||||
(unwind-protect
|
||||
(save-excursion
|
||||
(checkdoc-current-buffer t))
|
||||
(kill-buffer buf)))
|
||||
collected))
|
||||
|
||||
;;;###autoload
|
||||
(defun flymake-elisp-checkdoc (report-fn)
|
||||
"A Flymake backend for `checkdoc'.
|
||||
Calls REPORT-FN directly."
|
||||
(unless (derived-mode-p 'emacs-lisp-mode)
|
||||
(error "Can only work on `emacs-lisp-mode' buffers"))
|
||||
(funcall report-fn
|
||||
(cl-loop for (text start end _unfixable) in
|
||||
(flymake-elisp--checkdoc-1)
|
||||
collect
|
||||
(flymake-make-diagnostic
|
||||
(current-buffer)
|
||||
start end :note text))))
|
||||
|
||||
(defun flymake-elisp--byte-compile-done (report-fn
|
||||
origin-buffer
|
||||
output-buffer
|
||||
temp-file)
|
||||
(unwind-protect
|
||||
(with-current-buffer
|
||||
origin-buffer
|
||||
(save-excursion
|
||||
(save-restriction
|
||||
(widen)
|
||||
(funcall
|
||||
report-fn
|
||||
(ignore-errors
|
||||
(cl-loop with data =
|
||||
(with-current-buffer output-buffer
|
||||
(goto-char (point-min))
|
||||
(search-forward ":flymake-elisp-output-start")
|
||||
(read (point-marker)))
|
||||
for (string pos _fill level) in data
|
||||
do (goto-char pos)
|
||||
for beg = (if (< (point) (point-max))
|
||||
(point)
|
||||
(line-beginning-position))
|
||||
for end = (min
|
||||
(line-end-position)
|
||||
(or (cdr
|
||||
(bounds-of-thing-at-point 'sexp))
|
||||
(point-max)))
|
||||
collect (flymake-make-diagnostic
|
||||
(current-buffer)
|
||||
(if (= beg end) (1- beg) beg)
|
||||
end
|
||||
level
|
||||
string)))))))
|
||||
(kill-buffer output-buffer)
|
||||
(ignore-errors (delete-file temp-file))))
|
||||
|
||||
(defvar-local flymake-elisp--byte-compile-process nil
|
||||
"Buffer-local process started for byte-compiling the buffer.")
|
||||
|
||||
;;;###autoload
|
||||
(defun flymake-elisp-byte-compile (report-fn)
|
||||
"A Flymake backend for elisp byte compilation.
|
||||
Spawn an Emacs process that byte-compiles a file representing the
|
||||
current buffer state and calls REPORT-FN when done."
|
||||
(interactive (list (lambda (stuff)
|
||||
(message "aha %s" stuff))))
|
||||
(unless (derived-mode-p 'emacs-lisp-mode)
|
||||
(error "Can only work on `emacs-lisp-mode' buffers"))
|
||||
(when flymake-elisp--byte-compile-process
|
||||
(process-put flymake-elisp--byte-compile-process 'flymake-elisp--obsolete t)
|
||||
(when (process-live-p flymake-elisp--byte-compile-process)
|
||||
(kill-process flymake-elisp--byte-compile-process)))
|
||||
(let ((temp-file (make-temp-file "flymake-elisp-byte-compile"))
|
||||
(origin-buffer (current-buffer)))
|
||||
(save-restriction
|
||||
(widen)
|
||||
(write-region (point-min) (point-max) temp-file nil 'nomessage))
|
||||
(let* ((output-buffer (generate-new-buffer " *flymake-elisp-byte-compile*")))
|
||||
(setq
|
||||
flymake-elisp--byte-compile-process
|
||||
(make-process
|
||||
:name "flymake-elisp-byte-compile"
|
||||
:buffer output-buffer
|
||||
:command (list (expand-file-name invocation-name invocation-directory)
|
||||
"-Q"
|
||||
"--batch"
|
||||
;; "--eval" "(setq load-prefer-newer t)" ; for testing
|
||||
"-L" default-directory
|
||||
"-l" "flymake-elisp"
|
||||
"-f" "flymake-elisp--batch-byte-compile"
|
||||
temp-file)
|
||||
:connection-type 'pipe
|
||||
:sentinel
|
||||
(lambda (proc _event)
|
||||
(unless (process-live-p proc)
|
||||
(unwind-protect
|
||||
(cond
|
||||
((zerop (process-exit-status proc))
|
||||
(flymake-elisp--byte-compile-done report-fn
|
||||
origin-buffer
|
||||
output-buffer
|
||||
temp-file))
|
||||
((process-get proc 'flymake-elisp--obsolete)
|
||||
(flymake-log 3 "proc %s considered obsolete" proc))
|
||||
(t
|
||||
(funcall report-fn
|
||||
:panic
|
||||
:explanation (format "proc %s died violently" proc)))))))))
|
||||
:stderr null-device
|
||||
:noquery t)))
|
||||
|
||||
(defun flymake-elisp--batch-byte-compile (&optional file)
|
||||
"Helper for `flymake-elisp-byte-compile'.
|
||||
Runs in a batch-mode Emacs. Interactively use variable
|
||||
`buffer-file-name' for FILE."
|
||||
(interactive (list buffer-file-name))
|
||||
(let* ((file (or file
|
||||
(car command-line-args-left)))
|
||||
(dummy-elc-file)
|
||||
(byte-compile-log-buffer
|
||||
(generate-new-buffer " *dummy-byte-compile-log-buffer*"))
|
||||
(byte-compile-dest-file-function
|
||||
(lambda (source)
|
||||
(setq dummy-elc-file (make-temp-file (file-name-nondirectory source)))))
|
||||
(collected)
|
||||
(byte-compile-log-warning-function
|
||||
(lambda (string &optional position fill level)
|
||||
(push (list string position fill level)
|
||||
collected)
|
||||
t)))
|
||||
(unwind-protect
|
||||
(byte-compile-file file)
|
||||
(ignore-errors
|
||||
(delete-file dummy-elc-file)
|
||||
(kill-buffer byte-compile-log-buffer)))
|
||||
(prin1 :flymake-elisp-output-start)
|
||||
(terpri)
|
||||
(pp collected)))
|
||||
|
||||
(provide 'flymake-elisp)
|
||||
;;; flymake-elisp.el ends here
|
Loading…
Add table
Reference in a new issue