Skip to content

Instantly share code, notes, and snippets.

@orontee
Forked from ieure/python-pep8.el
Last active December 14, 2015 14:08
Show Gist options
  • Save orontee/5098024 to your computer and use it in GitHub Desktop.
Save orontee/5098024 to your computer and use it in GitHub Desktop.
;;; python-pep8.el --- minor mode for running `pep8'
;; Copyright (c) 2009, 2010 Ian Eure <[email protected]>
;; Copyright (c) 2013 Matthias Meulien <[email protected]>
;; Author: Ian Eure <[email protected]>
;; Keywords: languages python
;; Last edit: 2013-03-06
;; Version: 1.02
;; python-pep8.el is free software; you can redistribute it and/or modify it
;; under the terms of the GNU General Public License as published by the Free
;; Software Foundation; either version 2, or (at your option) any later
;; version.
;;
;; It is distributed in the hope that it will be useful, but WITHOUT ANY
;; WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
;; FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
;; details.
;;
;; You should have received a copy of the GNU General Public License along
;; with your copy of Emacs; see the file COPYING. If not, write to the Free
;; Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
;; 02111-1307, USA.
;;; Commentary:
;;
;; (autoload 'python-pep8 "python-pep8")
;; (autoload 'pep8 "python-pep8")
;;
;; Todo:
;;
;; - Sort by files and lines, or sort by error, warning (The sorting
;; must be done inside Emacs for portability)
;;
;;; Code:
(defgroup python-pep8 nil
"Check Python source code, according to PEP 8"
:prefix "python-pep8-"
:group 'tools
:link '(url-link "http://www.python.org/dev/peps/pep-0008/"))
(defvar python-pep8-last-buffer nil
"The most recent PEP8 buffer.
A PEP8 buffer becomes most recent when you select PEP8 mode in it.
Notice that using \\[next-error] or \\[compile-goto-error] modifies
`complation-last-buffer' rather than `python-pep8-last-buffer'.")
(defconst python-pep8-regexp-alist
(let ((base "^\\(.*\\):\\([0-9]+\\):\\([0-9]+\\):\s+\\(%s[0-9]+ .*\\)"))
(list (list (format base "E") 1 2 3 2)
(list (format base "W") 1 2 3 1)))
"Regexp used to match PEP8 hits. See `compilation-error-regexp-alist'.")
(defcustom python-pep8-options nil
"Options to pass to command"
:type '(repeat string)
:group 'python-pep8)
(defcustom python-pep8-command "pep8"
"Command name."
:type '(file)
:group 'python-pep8)
(defcustom python-pep8-ask-about-save t
"Non-nil to ask which buffers to save before compiling.
Otherwise, it saves all modified buffers without asking."
:type 'boolean
:group 'python-pep8)
(defcustom python-pep8-ignore nil
"Errors and warnings to skip (e.g. E4 or W191).
Groups of errors and warnings:
- E errors
- W warnings
- 100 indentation
- 200 whitespace
- 300 blank lines
- 400 imports
- 500 line length
- 600 deprecation
- 700 statements
- 900 syntax error"
:type '(repeat string)
:group 'python-pep8)
(defun python-pep8-add-to-ignore ()
"Add error or warning to `python-pep8-ignore'.
The current line is parsed to identify an error or a warning."
(interactive)
(or (compilation-buffer-p (current-buffer))
(error "Not in a compilation buffer"))
;; TODO Check that we are on an error line
(let ((reg "^.*:[0-9]+:[0-9]+:\s+\\(\\(W\\|E\\)[0-9]+\\)"))
(save-excursion
(goto-char (line-beginning-position))
(cond
((looking-at reg)
(let ((code (buffer-substring-no-properties
(match-beginning 1) (match-end 1))))
(add-to-list 'python-pep8-ignore code)
(message (concat "Ignoring %s "
(or (and (equal (match-string 2) "W") "warnings")
"errors")) code)))
(t (message "No error or warning code found"))))))
(require 'compile)
(defvar python-pep8-mode-map
(let ((map (make-sparse-keymap)))
(set-keymap-parent map compilation-minor-mode-map)
(define-key map "i" 'python-pep8-add-to-ignore)
map)
"Keymap for PEP8 buffers.
`compilation-minor-mode-map' is a cdr of this.")
(define-compilation-mode python-pep8-mode "PEP8"
(setq python-pep8-last-buffer (current-buffer))
(set (make-local-variable 'compilation-error-regexp-alist)
python-pep8-regexp-alist)
(set (make-local-variable 'compilation-disable-input) t))
;;;###autoload
(defun python-pep8 ()
"Call `python-pep8-command' to check Python source code.
If the current buffer is not visiting a file, the check is
performed on all files with *.py extension in its default
directory.
While pep8 runs asynchronously, you can use \\[next-error] (M-x next-error),
or \\<python-pep8-mode-map>\\[compile-goto-error] in the \
output buffer, to go to the lines where pep8 found matches."
(interactive)
(save-some-buffers (not python-pep8-ask-about-save) nil)
(require 'tramp)
(let* ((tramp (tramp-tramp-file-p (buffer-file-name)))
(file (or (and tramp
(aref (tramp-dissect-file-name (buffer-file-name)) 3))
(buffer-file-name)
default-directory))
(ignore (mapconcat 'identity python-pep8-ignore ","))
(command (mapconcat
'identity
(list python-pep8-command
(mapconcat 'identity
(if (eq (length ignore) 0)
python-pep8-options
(append python-pep8-options
(list "--ignore" ignore)))
" ")
(comint-quote-filename file)) " ")))
(compilation-start command 'python-pep8-mode)))
;;;###autoload
(defalias 'pep8 'python-pep8)
(provide 'python-pep8)
;;; python-pep8.el ends here
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment