Function: sh-shellcheck-flymake

sh-shellcheck-flymake is a byte-compiled function defined in sh-script.el.gz.

Signature

(sh-shellcheck-flymake REPORT-FN &rest ARGS)

Documentation

Flymake backend using the shellcheck program.

Takes a Flymake callback REPORT-FN as argument, as expected of a member of flymake-diagnostic-functions.

Source Code

;; Defined in /usr/src/emacs/lisp/progmodes/sh-script.el.gz
(defun sh-shellcheck-flymake (report-fn &rest _args)
  "Flymake backend using the shellcheck program.
Takes a Flymake callback REPORT-FN as argument, as expected of a
member of `flymake-diagnostic-functions'."
  (when (process-live-p sh--shellcheck-process)
    (kill-process sh--shellcheck-process))
  (let* ((source (current-buffer))
         (dialect (named-let recur ((s sh-shell))
                    (pcase s
                      ((or 'bash 'dash 'sh) (symbol-name s))
                      ('ksh88 "ksh")
                      ((guard s)
                       (recur (alist-get s sh-ancestor-alist))))))
         (sentinel
          (lambda (proc _event)
            (when (memq (process-status proc) '(exit signal))
              (unwind-protect
                  (if (with-current-buffer source
                        (not (eq proc sh--shellcheck-process)))
                      (flymake-log :warning "Canceling obsolete check %s" proc)
                    (with-current-buffer (process-buffer proc)
                      (goto-char (point-min))
                      (thread-last
                        (sh--json-read)
                        (alist-get 'comments)
                        (seq-filter
                         (lambda (item)
                           (let-alist item (string= .file "-"))))
                        (mapcar
                         (lambda (item)
                           (let-alist item
                             (flymake-make-diagnostic
                              source
                              (cons .line .column)
                              (unless (and (eq .line .endLine)
                                           (eq .column .endColumn))
                                (cons .endLine .endColumn))
                              (pcase .level
                                ("error" :error)
                                ("warning" :warning)
                                (_ :note))
                              (format "SC%s: %s" .code .message)))))
                        (funcall report-fn))))
                (kill-buffer (process-buffer proc)))))))
    (unless dialect
      (error "`sh-shellcheck-flymake' is not suitable for shell type `%s'"
             sh-shell))
    (setq sh--shellcheck-process
          (make-process
           :name "shellcheck" :noquery t :connection-type 'pipe
           :buffer (generate-new-buffer " *flymake-shellcheck*")
           :command `(,sh-shellcheck-program
                      "--format=json1"
                      "-s" ,dialect
                      ,@sh-shellcheck-arguments
                      "-")
           :sentinel sentinel))
    (save-restriction
      (widen)
      (process-send-region sh--shellcheck-process (point-min) (point-max))
      (process-send-eof sh--shellcheck-process))))