From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.io!.POSTED.blaine.gmane.org!not-for-mail From: Augusto Stoffel Newsgroups: gmane.emacs.bugs Subject: bug#57884: [PATCH] Flymake backend using the shellcheck program Date: Sun, 18 Sep 2022 14:38:34 +0200 Message-ID: <87fsgoyi0l.fsf@gmail.com> References: <87a66yaqwc.fsf@gmail.com> <83bkre0w4m.fsf@gnu.org> <871qs9c3er.fsf@gmail.com> <87zgewdhhd.fsf@posteo.net> Mime-Version: 1.0 Content-Type: multipart/mixed; boundary="=-=-=" Injection-Info: ciao.gmane.io; posting-host="blaine.gmane.org:116.202.254.214"; logging-data="14340"; mail-complaints-to="usenet@ciao.gmane.io" User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/29.0.50 (gnu/linux) Cc: Eli Zaretskii , 57884@debbugs.gnu.org, Stefan Kangas To: Philip Kaludercic Original-X-From: bug-gnu-emacs-bounces+geb-bug-gnu-emacs=m.gmane-mx.org@gnu.org Sun Sep 18 14:40:08 2022 Return-path: Envelope-to: geb-bug-gnu-emacs@m.gmane-mx.org Original-Received: from lists.gnu.org ([209.51.188.17]) by ciao.gmane.io with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1oZtai-0003am-CH for geb-bug-gnu-emacs@m.gmane-mx.org; Sun, 18 Sep 2022 14:40:08 +0200 Original-Received: from localhost ([::1]:41794 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1oZtah-0001if-Ej for geb-bug-gnu-emacs@m.gmane-mx.org; Sun, 18 Sep 2022 08:40:07 -0400 Original-Received: from eggs.gnu.org ([2001:470:142:3::10]:56978) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1oZtZe-0001hG-U9 for bug-gnu-emacs@gnu.org; Sun, 18 Sep 2022 08:39:03 -0400 Original-Received: from debbugs.gnu.org ([209.51.188.43]:49168) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1oZtZe-0001V5-3w for bug-gnu-emacs@gnu.org; Sun, 18 Sep 2022 08:39:02 -0400 Original-Received: from Debian-debbugs by debbugs.gnu.org with local (Exim 4.84_2) (envelope-from ) id 1oZtZd-00005j-QS for bug-gnu-emacs@gnu.org; Sun, 18 Sep 2022 08:39:01 -0400 X-Loop: help-debbugs@gnu.org Resent-From: Augusto Stoffel Original-Sender: "Debbugs-submit" Resent-CC: bug-gnu-emacs@gnu.org Resent-Date: Sun, 18 Sep 2022 12:39:01 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: followup 57884 X-GNU-PR-Package: emacs X-GNU-PR-Keywords: patch Original-Received: via spool by 57884-submit@debbugs.gnu.org id=B57884.1663504730323 (code B ref 57884); Sun, 18 Sep 2022 12:39:01 +0000 Original-Received: (at 57884) by debbugs.gnu.org; 18 Sep 2022 12:38:50 +0000 Original-Received: from localhost ([127.0.0.1]:48246 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1oZtZR-000059-J8 for submit@debbugs.gnu.org; Sun, 18 Sep 2022 08:38:50 -0400 Original-Received: from mail-ed1-f53.google.com ([209.85.208.53]:37394) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1oZtZK-0008WD-JD for 57884@debbugs.gnu.org; Sun, 18 Sep 2022 08:38:46 -0400 Original-Received: by mail-ed1-f53.google.com with SMTP id a41so25714362edf.4 for <57884@debbugs.gnu.org>; Sun, 18 Sep 2022 05:38:42 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=mime-version:user-agent:message-id:date:references:in-reply-to :subject:cc:to:from:from:to:cc:subject:date; bh=uPlgipz+03fYbHpfjtPpYxpsJWcgz0n0cV760n7YoFw=; b=fr6BbqwJCSP61OhC7iCMXt4KGvps0PuouTOFEUtIHLEMPcbYv8f4i651h/uKn2m5D2 yCIiG4Qa5miHJwX/2X4uHl9X3pyGy65HHPO92nG3yk5ppSg6vmrzqDgwinA4JFVd45E7 Os8oU/zTlPWVdqzbO1WSKCuEUBAONHMHbebdftypqNrJr3Kdrfe/KVIzvkK1ywBSsWAV 6eDmzV9ndqVu+cbAHha/IHbZJsvnHEEJZISGWB/UPnp7rCUiTHGq5aAq+FZn11qL3Wv7 a7HNoB2z3zuWM8ruAqJySQOCJT1hhKD5qWL+dbrR/4MNNpHJDJGy3oI+0S4Y1pP7XEif ZPBg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=mime-version:user-agent:message-id:date:references:in-reply-to :subject:cc:to:from:x-gm-message-state:from:to:cc:subject:date; bh=uPlgipz+03fYbHpfjtPpYxpsJWcgz0n0cV760n7YoFw=; b=N2iWJtMKsY1KdcvmLt2KtLHUU3s4bg+9cRNrpbfwm70YuF4zxHI5zUgDscqGrVXij9 p50pXNdkVP9wcz6v5X9+Q9grJeryWc6fG3XWdD23SrrxA54BGjN82W5otzF1u2hRVK03 oI432M1Fx5jkt/hTSl5aGXkkdo4Z4rcnfRwD88x31xxfDafxvrLAKA8WYgjJNwj5V3Bp T3tsz21SywBEIRmNKgEVFTH4ELUBE8FaG8STHMvdA59L6MX/n+Lq7YnLABNhCFD/YZQQ DrUmqYzF8dLTc75BRVNNVU1RhcqCbJSJhayOTrwc2k/XxEeM5KuYeUQ2oyGv/0E4jN4+ EHfw== X-Gm-Message-State: ACrzQf2pellHW2kGj2xJUyk7BSF5gnGkv/o0yrsNl15oZ+8hVgMZ9Y7T NZT4LBsatx3bbfiMMwUO0+c= X-Google-Smtp-Source: AMsMyM78YPT+8qMZebnsC14u3VcBaFaMyATB+RKc+ZLerwCTA3C978Qtex7+6G0cbXyj0eZwCTHy9Q== X-Received: by 2002:a05:6402:26d2:b0:451:5a8c:346b with SMTP id x18-20020a05640226d200b004515a8c346bmr11208497edd.424.1663504716615; Sun, 18 Sep 2022 05:38:36 -0700 (PDT) Original-Received: from ars3 ([2a02:8109:8ac0:56d0::8510]) by smtp.gmail.com with ESMTPSA id o18-20020a170906769200b007386a8b90c9sm14113295ejm.13.2022.09.18.05.38.35 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 18 Sep 2022 05:38:35 -0700 (PDT) In-Reply-To: <87zgewdhhd.fsf@posteo.net> (Philip Kaludercic's message of "Sun, 18 Sep 2022 11:55:42 +0000") X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list X-BeenThere: bug-gnu-emacs@gnu.org List-Id: "Bug reports for GNU Emacs, the Swiss army knife of text editors" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: bug-gnu-emacs-bounces+geb-bug-gnu-emacs=m.gmane-mx.org@gnu.org Original-Sender: "bug-gnu-emacs" Xref: news.gmane.io gmane.emacs.bugs:242980 Archived-At: --=-=-= Content-Type: text/plain With the attached patch I believe I've addressed all comments from this and previous messages. (In case I missed some detail, the committer should feel free to make any desired copyediting.) --=-=-= Content-Type: text/x-patch Content-Disposition: attachment; filename=0001-New-Flymake-backend-using-the-shellcheck-program.patch >From 1cadf763114eb733036a1c8182900fe2df17092c Mon Sep 17 00:00:00 2001 From: Augusto Stoffel Date: Sat, 17 Sep 2022 18:30:04 +0200 Subject: [PATCH] New Flymake backend using the shellcheck program See bug#57884. * lisp/progmodes/sh-script.el (sh-shellcheck-program, sh--shellcheck-process, sh-shellcheck-flymake): Variables and function defining a Flymake backend. (sh-mode): Add it to 'flymake-diagnostic-functions'. --- etc/NEWS | 4 ++ lisp/progmodes/sh-script.el | 76 +++++++++++++++++++++++++++++++++++++ 2 files changed, 80 insertions(+) diff --git a/etc/NEWS b/etc/NEWS index a6a8883593..5b2ed16063 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -1320,6 +1320,10 @@ This controls how statements like the following are indented: foo && bar +*** New Flymake backend using the ShellCheck program +It is enabled by default, but requires that the external "shellcheck" +command is installed. + ** Cperl Mode --- diff --git a/lisp/progmodes/sh-script.el b/lisp/progmodes/sh-script.el index 517fbbd8e7..dd36f92766 100644 --- a/lisp/progmodes/sh-script.el +++ b/lisp/progmodes/sh-script.el @@ -31,6 +31,9 @@ ;; available for filenames, variables known from the script, the shell and ;; the environment as well as commands. +;; A Flymake backend using the "shellcheck" program is provided. See +;; https://www.shellcheck.net/ for installation instructions. + ;;; Known Bugs: ;; - In Bourne the keyword `in' is not anchored to case, for, select ... @@ -1580,6 +1583,7 @@ sh-mode ((equal (file-name-nondirectory buffer-file-name) ".profile") "sh") (t sh-shell-file)) nil nil) + (add-hook 'flymake-diagnostic-functions #'sh-shellcheck-flymake nil t) (add-hook 'hack-local-variables-hook #'sh-after-hack-local-variables nil t)) @@ -3103,6 +3107,78 @@ sh-delete-backslash (delete-region (1+ (point)) (progn (skip-chars-backward " \t") (point))))))) +;;; Flymake backend + +(defcustom sh-shellcheck-program "shellcheck" + "Name of the shellcheck executable." + :type 'string + :version "29.1") + +(defcustom sh-shellcheck-arguments nil + "Additional arguments to the shellcheck program." + :type '(repeat string) + :version "29.1") + +(defvar-local sh--shellcheck-process nil) + +(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 dialect ((s sh-shell)) + (pcase s + ((or 'bash 'dash 'sh) (symbol-name s)) + ('ksh88 "ksh") + ((guard s) + (dialect (alist-get s sh-ancestor-alist)))))) + (pattern "^-:\\([0-9]+\\):\\([0-9]+\\): \\([^:]+\\): \\(.*\\)$") + (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)) + (cl-loop + while (search-forward-regexp pattern nil t) + for msg = (match-string 4) + for (beg . end) = (flymake-diag-region + source + (string-to-number (match-string 1)) + (string-to-number (match-string 2))) + for type = (pcase (match-string 3) + ("error" :error) + ("warning" :warning) + (_ :note)) + when (and beg end) + collect (flymake-make-diagnostic source beg end type msg) + into diags + finally (funcall report-fn diags)))) + (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=gcc" + "--color=never" + "-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)))) + (provide 'sh-script) ;;; sh-script.el ends here -- 2.37.3 --=-=-= Content-Type: text/plain On Sun, 18 Sep 2022 at 11:55, Philip Kaludercic wrote: > Augusto Stoffel writes: > >> >> I could split this into two defcustoms if you feel strongly about it, >> but it seems a bit of overengineering to me. Not many people will want >>to customize the program name, and the switches would have to be >> provided as a list anyway, since we're not going to call this through a >> shell. > > I think it would be good, because then you could make the flags file > local in case you need something special, without having to worry about > some evil file that sets the command to > > '("rm" "-rf" "--no-preserve-root" "/") > Well, fine then. I've split this into two variables. > I don't use `named-let' that much, but calling both the result and the > recursive function `dialect' seems confusing to me. > Welcome to Lisp-2... >> + (pattern "^-:\\([0-9]+\\):\\([0-9]+\\): \\([^:]+\\): \\(.*\\)$") > > Do you think that that using `rx' would make this pattern more maintainable? > I use rx often, but I think this is still at a level where rx doesn't really help much. >> + (sentinel >> + (lambda (proc _event) > > Wouldn't it be cleaner to pull this lambda out into a separate named function? > That's not possible, it needs to be in that lexical scope. >> + (setq sh--shellcheck-process >> + (make-process >> + :name "luacheck" :noquery t :connection-type 'pipe > ^ > Typo? > >> + :buffer (generate-new-buffer " *flymake-luacheck*") > ^ > same here Ouch, fixed. > Also what happens if someone doesn't have shellcheck installed? Then Flymake logs a warning and disables the backend. The error message will be whatever make-process gives, which I find more than good enough. --=-=-=--