From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.org!.POSTED!not-for-mail From: Lele Gaifax Newsgroups: gmane.emacs.devel Subject: [PATCH] Implement Python backend for Flymake Date: Fri, 13 Oct 2017 11:04:48 +0200 Organization: Nautilus Entertainments Message-ID: <87y3of2zbj.fsf@metapensiero.it> NNTP-Posting-Host: blaine.gmane.org Mime-Version: 1.0 Content-Type: multipart/mixed; boundary="=-=-=" X-Trace: blaine.gmane.org 1507885579 14693 195.159.176.226 (13 Oct 2017 09:06:19 GMT) X-Complaints-To: usenet@blaine.gmane.org NNTP-Posting-Date: Fri, 13 Oct 2017 09:06:19 +0000 (UTC) User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/26.0.60 (gnu/linux) To: emacs-devel@gnu.org Original-X-From: emacs-devel-bounces+ged-emacs-devel=m.gmane.org@gnu.org Fri Oct 13 11:06:15 2017 Return-path: Envelope-to: ged-emacs-devel@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 1e2vux-0002YC-52 for ged-emacs-devel@m.gmane.org; Fri, 13 Oct 2017 11:06:07 +0200 Original-Received: from localhost ([::1]:49106 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1e2vv4-0003PI-LY for ged-emacs-devel@m.gmane.org; Fri, 13 Oct 2017 05:06:14 -0400 Original-Received: from eggs.gnu.org ([2001:4830:134:3::10]:37755) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1e2vuQ-0003PC-DT for emacs-devel@gnu.org; Fri, 13 Oct 2017 05:05:35 -0400 Original-Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1e2vuJ-0007jy-SV for emacs-devel@gnu.org; Fri, 13 Oct 2017 05:05:34 -0400 Original-Received: from [195.159.176.226] (port=34379 helo=blaine.gmane.org) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1e2vuJ-0007j9-8i for emacs-devel@gnu.org; Fri, 13 Oct 2017 05:05:27 -0400 Original-Received: from list by blaine.gmane.org with local (Exim 4.84_2) (envelope-from ) id 1e2vtv-0004Q4-BD for emacs-devel@gnu.org; Fri, 13 Oct 2017 11:05:03 +0200 X-Injected-Via-Gmane: http://gmane.org/ Original-Lines: 194 Original-X-Complaints-To: usenet@blaine.gmane.org Cancel-Lock: sha1:pGc5NbcVWc3jpsocR1a23jwAc6A= X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 195.159.176.226 X-BeenThere: emacs-devel@gnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: "Emacs development discussions." List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: emacs-devel-bounces+ged-emacs-devel=m.gmane.org@gnu.org Original-Sender: "Emacs-devel" Xref: news.gmane.org gmane.emacs.devel:219442 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: 8bit -- nickname: Lele Gaifax | Quando vivrò di quello che ho pensato ieri real: Emanuele Gaifas | comincerò ad aver paura di chi mi copia. lele@metapensiero.it | -- Fortunato Depero, 1929. --=-=-=--