From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.org!.POSTED!not-for-mail From: Lele Gaifax Newsgroups: gmane.emacs.bugs Subject: bug#28808: [PATCH] Implement Python backend for Flymake Date: Fri, 13 Oct 2017 11:54:13 +0200 Message-ID: <87lgkf2x16.fsf@metapensiero.it> NNTP-Posting-Host: blaine.gmane.org Mime-Version: 1.0 Content-Type: multipart/mixed; boundary="=-=-=" X-Trace: blaine.gmane.org 1507888519 6619 195.159.176.226 (13 Oct 2017 09:55:19 GMT) X-Complaints-To: usenet@blaine.gmane.org NNTP-Posting-Date: Fri, 13 Oct 2017 09:55:19 +0000 (UTC) To: 28808@debbugs.gnu.org Original-X-From: bug-gnu-emacs-bounces+geb-bug-gnu-emacs=m.gmane.org@gnu.org Fri Oct 13 11:55:10 2017 Return-path: Envelope-to: geb-bug-gnu-emacs@m.gmane.org Original-Received: from lists.gnu.org ([208.118.235.17]) by blaine.gmane.org with esmtp (Exim 4.84_2) (envelope-from ) id 1e2wgM-0000JN-Oi for geb-bug-gnu-emacs@m.gmane.org; Fri, 13 Oct 2017 11:55:06 +0200 Original-Received: from localhost ([::1]:49353 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1e2wgU-0003CK-9p for geb-bug-gnu-emacs@m.gmane.org; Fri, 13 Oct 2017 05:55:14 -0400 Original-Received: from eggs.gnu.org ([2001:4830:134:3::10]:49729) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1e2wgN-0003CF-5v for bug-gnu-emacs@gnu.org; Fri, 13 Oct 2017 05:55:08 -0400 Original-Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1e2wgJ-0005lU-VJ for bug-gnu-emacs@gnu.org; Fri, 13 Oct 2017 05:55:07 -0400 Original-Received: from debbugs.gnu.org ([208.118.235.43]:56451) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1e2wgJ-0005kx-Qc for bug-gnu-emacs@gnu.org; Fri, 13 Oct 2017 05:55:03 -0400 Original-Received: from Debian-debbugs by debbugs.gnu.org with local (Exim 4.84_2) (envelope-from ) id 1e2wgJ-0000ZS-H6 for bug-gnu-emacs@gnu.org; Fri, 13 Oct 2017 05:55:03 -0400 X-Loop: help-debbugs@gnu.org Resent-From: Lele Gaifax Original-Sender: "Debbugs-submit" Resent-CC: bug-gnu-emacs@gnu.org Resent-Date: Fri, 13 Oct 2017 09:55:03 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: report 28808 X-GNU-PR-Package: emacs X-GNU-PR-Keywords: patch X-Debbugs-Original-To: bug-gnu-emacs@gnu.org Original-Received: via spool by submit@debbugs.gnu.org id=B.15078884762145 (code B ref -1); Fri, 13 Oct 2017 09:55:03 +0000 Original-Received: (at submit) by debbugs.gnu.org; 13 Oct 2017 09:54:36 +0000 Original-Received: from localhost ([127.0.0.1]:36899 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1e2wfr-0000YW-Gz for submit@debbugs.gnu.org; Fri, 13 Oct 2017 05:54:35 -0400 Original-Received: from eggs.gnu.org ([208.118.235.92]:58677) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1e2wfp-0000YK-Lg for submit@debbugs.gnu.org; Fri, 13 Oct 2017 05:54:34 -0400 Original-Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1e2wfi-0005GH-Pg for submit@debbugs.gnu.org; Fri, 13 Oct 2017 05:54:28 -0400 Original-Received: from lists.gnu.org ([2001:4830:134:3::11]:49254) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1e2wfi-0005GD-Ll for submit@debbugs.gnu.org; Fri, 13 Oct 2017 05:54:26 -0400 Original-Received: from eggs.gnu.org ([2001:4830:134:3::10]:49643) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1e2wfg-00033Z-LW for bug-gnu-emacs@gnu.org; Fri, 13 Oct 2017 05:54:26 -0400 Original-Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1e2wfd-0005CY-IQ for bug-gnu-emacs@gnu.org; Fri, 13 Oct 2017 05:54:24 -0400 Original-Received: from mail.arstecnica.it ([144.76.81.238]:40550) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1e2wfd-0005B0-7c for bug-gnu-emacs@gnu.org; Fri, 13 Oct 2017 05:54:21 -0400 Original-Received: from nautilus (assp.arstecnica.it [192.168.1.102]) by mail.arstecnica.it (Postfix) with ESMTPSA id 8C63A83EC71 for ; Fri, 13 Oct 2017 09:54:14 +0000 (UTC) Original-Received: from nautilus ([31.44.165.109] helo=nautilus) by assp.arstecnica.it with SMTPS(AES256-GCM-SHA384) (2.3.3); 13 Oct 2017 09:54:13 +0000 X-Assp-Version: 2.3.3(14029) on assp.arstecnica.it X-Assp-ID: assp.arstecnica.it m1-88454-03815 X-Assp-Session: A71666BC (mail 1) X-Assp-Envelope-From: lele@metapensiero.it X-Assp-Intended-For: bug-gnu-emacs@gnu.org X-Assp-Client-TLS: yes X-Assp-Server-TLS: yes X-detected-operating-system: by eggs.gnu.org: GNU/Linux 3.x [fuzzy] X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.6.x X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] X-Received-From: 208.118.235.43 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.org@gnu.org Original-Sender: "bug-gnu-emacs" Xref: news.gmane.org gmane.emacs.bugs:138333 Archived-At: --=-=-= Content-Type: text/plain Hi, here below you can find an implementation of a Python backend for the new Flymake facility. I'm quite satisfied by it: I tested both the default settings (targeting `pyflakes') and the `flake8' customization suggested in the docstrings. As always, I'm willing to apply whatever tweak/fix you may find reasonable. Thanks a lot, ciao, lele. --=-=-= Content-Type: text/x-diff Content-Disposition: inline; filename=0001-Fix-typo.patch >From 16828afebe3e732e3cbf856b093dfff65d3319ff Mon Sep 17 00:00:00 2001 From: Lele Gaifax Date: Fri, 13 Oct 2017 10:43:13 +0200 Subject: [PATCH 1/2] Fix typo --- lisp/progmodes/flymake.el | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lisp/progmodes/flymake.el b/lisp/progmodes/flymake.el index 8c9c4b211a..8fa763a4b8 100644 --- a/lisp/progmodes/flymake.el +++ b/lisp/progmodes/flymake.el @@ -124,7 +124,7 @@ flymake-gui-warnings-enabled "it no longer has any effect." "26.1") (defcustom flymake-start-on-flymake-mode t - "Start syntax check when `flymake-mode'is enabled. + "Start syntax check when `flymake-mode' is enabled. Specifically, start it when the buffer is actually displayed." :type 'boolean) -- 2.15.0.rc0 --=-=-= Content-Type: text/x-diff Content-Disposition: inline; filename=0002-Add-a-Flymake-backend-for-Python.patch >From 84a4dd4ef7a6ae9e49cb7442070744b5d6e3ec95 Mon Sep 17 00:00:00 2001 From: Lele Gaifax Date: Fri, 13 Oct 2017 10:44:02 +0200 Subject: [PATCH 2/2] Add a Flymake backend for Python * lisp/progmodes/python.el: Implement new Flymake backend with related customizable settings. (python-flymake-command, python-flymake-command-output-regexp, python-flymake-msg-alist): New defcustom. (python-flymake): New function. (python-flymake-activate): New function. --- lisp/progmodes/python.el | 101 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 101 insertions(+) diff --git a/lisp/progmodes/python.el b/lisp/progmodes/python.el index f79d9a47d3..866e02ffbd 100644 --- a/lisp/progmodes/python.el +++ b/lisp/progmodes/python.el @@ -5141,6 +5141,107 @@ python-util-valid-regexp-p (ignore-errors (string-match regexp "") t)) +;;; Flymake integration + +(defgroup python-flymake nil + "Integration between Python and Flymake." + :group 'python + :link '(custom-group-link :tag "Flymake" flymake) + :version "26.1") + +(defcustom python-flymake-command '("pyflakes") + "The external tool that will be used to perform the syntax check. +This is a non empty list of strings, the checker tool possibly followed by +required arguments: to use `flake8' you would set this to (\"flake8\" \"-\")." + :group 'python-flymake + :type '(repeat string)) + +;; The default regexp accomodates for older pyflakes, which did not +;; report the column number +(defcustom python-flymake-command-output-regexp + "^\\(?:\\):\\(?1:[0-9]+\\):\\(?:\\(?2:[0-9]+\\):\\)? \\(?3:.*\\)$" + "The regexp used to parse the output of the specified tool. +It must contain two or three groups: group 1 is the line number, group 2 the +optional column number and the third is the actual message." + :group 'python-flymake + :type 'regexp) + +(defcustom python-flymake-msg-alist + '(("\\(^redefinition\\|.*unused.*\\|used$\\)" . :warning)) + "Alist used to associate messages to their types. +Each element should be a cons-cell (REGEXP . TYPE), where TYPE must be +one defined in the variable `flymake-diagnostic-types-alist'. +For example, when using `flake8' a possible configuration could be: + + ((\"\\(^redefinition\\|.*unused.*\\|used$\\)\" . :warning) + (\"^E999\" . :error) + (\"^[EW][0-9]+\" . :note)) + +By default messages are considered errors." + :group 'python-flymake + :type `(alist :key-type (regexp) + :value-type (symbol))) + +(defvar-local python--flymake-proc nil) + +(defun python-flymake (report-fn &rest _args) + "Flymake backend for Python. +This backend uses `python-flymake-command' (which see) to launch a process +that is passed the current buffer's content via stdin. +REPORT-FN is Flymake's callback function." + (unless (executable-find (car python-flymake-command)) + (error "Cannot find a suitable checker")) + + (unless (derived-mode-p 'python-mode) + (error "Can only work on `python-mode' buffers")) + + (when (process-live-p python--flymake-proc) + (kill-process python--flymake-proc)) + + (let ((source (current-buffer))) + (save-restriction + (widen) + (setq python--flymake-proc + (make-process + :name "python-flymake" + :noquery t + :connection-type 'pipe + :buffer (generate-new-buffer " *python-flymake*") + :command python-flymake-command + :sentinel + (lambda (proc _event) + (when (eq 'exit (process-status proc)) + (unwind-protect + (when (eq proc python--flymake-proc) + (with-current-buffer (process-buffer proc) + (goto-char (point-min)) + (cl-loop + while (search-forward-regexp + python-flymake-command-output-regexp nil t) + for msg = (match-string 3) + for (beg . end) = (flymake-diag-region + source + (string-to-number (match-string 1)) + (and (match-string 2) + (string-to-number + (match-string 2)))) + for type = (or (assoc-default msg + python-flymake-msg-alist + #'string-match) + :error) + collect (flymake-make-diagnostic + source beg end type msg) + into diags + finally (funcall report-fn diags)))) + (kill-buffer (process-buffer proc))))))) + (process-send-region python--flymake-proc (point-min) (point-max)) + (process-send-eof python--flymake-proc)))) + +(defun python-flymake-activate () + "Activate the Flymake syntax check on all python-mode buffers." + (add-hook 'flymake-diagnostic-functions #'python-flymake nil t)) + + (defun python-electric-pair-string-delimiter () (when (and electric-pair-mode (memq last-command-event '(?\" ?\')) -- 2.15.0.rc0 --=-=-= Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: quoted-printable --=20 nickname: Lele Gaifax | Quando vivr=C3=B2 di quello che ho pensato ieri real: Emanuele Gaifas | comincer=C3=B2 ad aver paura di chi mi copia. lele@metapensiero.it | -- Fortunato Depero, 1929. --=-=-=--