emacs-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Flymake refactored


From: Lele Gaifax
Subject: Re: Flymake refactored
Date: Thu, 05 Oct 2017 13:28:46 +0200
User-agent: Gnus/5.13 (Gnus v5.13) Emacs/26.0.60 (gnu/linux)

address@hidden (João Távora) writes:

> For example, here's a decent Ruby checker under 40 lines that does the
> same as MELPA's flymake-ruby.el (which is based on flymake-easy), but
> using the new API and without creating any temporary files.

Thank you João for the example, I'm attaching below my Python pyflakes
variant, that seems working pretty well.

I have a couple of questions:

a) I had to use lexical-binding, otherwise the funcall form in the inner
   lambda raises an error about report-fn being undefined; did I miss
   something, or is that the right thing to do?

b) I had to omit the "local" flag when hooking esk/python-flymake to
   flymake-diagnostic-functions as you did in the example: shouldn't the
   latter be a defvar-local variable?

Thanks in advance,
ciao, lele.



;; excerpt from my .emacs.d/esk/python.el -- -*- lexical-binding:t -*-
;;

;; TODO: Maybe defcustom the following two?
(defvar esk/python-flymake-command '("python3.6" "-m" "pyflakes"))
(defvar esk/python-flymake-warning-regexp 
"\\(^redefinition\\|.*unused.*\\|used$\\)")

(defvar-local esk/python--flymake-proc nil)

;; Explicitly use Python 3.6, to handle f-strings
(defvar esk/python-flymake-command '("python3.6" "-m" "pyflakes"))

;; Accomodate for older pyflakes, which did not report the column number
(defvar esk/python-flymake-diag-regexp
  "^\\(?:.*\\.p[yj]\\|<stdin>\\):\\([0-9]+\\):\\(?:\\([0-9]+\\):\\)? \\(.*\\)$")

;; Recognize warning messages
(defvar esk/python-flymake-warn-msg-regexp 
"\\(^redefinition\\|.*unused.*\\|used$\\)")

(defvar-local esk/python--flymake-proc nil)

(defun esk/python-flymake (report-fn &rest _args)
  (unless (executable-find (car esk/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 esk/python--flymake-proc)
    (kill-process esk/python--flymake-proc))

  (let ((source (current-buffer)))
    (save-restriction
      (widen)
      (setq esk/python--flymake-proc
            (make-process
             :name "python-flymake"
             :noquery t
             :connection-type 'pipe
             :buffer (generate-new-buffer " *python-flymake*")
             :command esk/python-flymake-command
             :sentinel
             (lambda (proc _event)
               (unwind-protect
                   (with-current-buffer (process-buffer proc)
                     (goto-char (point-min))
                     (cl-loop
                      while (search-forward-regexp 
esk/python-flymake-diag-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 = (if (string-match 
esk/python-flymake-warn-msg-regexp msg)
                                     :warning :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 esk/python--flymake-proc (point-min) (point-max))
      (process-send-eof esk/python--flymake-proc))))

(add-hook 'flymake-diagnostic-functions #'esk/python-flymake)
(add-hook 'python-mode-hook #'flymake-mode-on)

-- 
nickname: Lele Gaifax | Quando vivrò di quello che ho pensato ieri
real: Emanuele Gaifas | comincerò ad aver paura di chi mi copia.
address@hidden  |                 -- Fortunato Depero, 1929.




reply via email to

[Prev in Thread] Current Thread [Next in Thread]