Key stuff
Summary: Test Plan: Reviewers: Subscribers: Tasks: Tags:
This commit is contained in:
parent
7ebc828269
commit
82767c9896
3 changed files with 139 additions and 8 deletions
124
site-lisp/blacken.el
Normal file
124
site-lisp/blacken.el
Normal file
|
|
@ -0,0 +1,124 @@
|
|||
;;; blacken.el --- Reformat python buffers using the "black" formatter
|
||||
|
||||
;; Copyright (C) 2018 Artem Malyshev
|
||||
|
||||
;; Author: Artem Malyshev <proofit404@gmail.com>
|
||||
;; Homepage: https://github.com/proofit404/blacken
|
||||
;; Version: 0.0.1
|
||||
;; Package-Requires: ((emacs "25.2"))
|
||||
|
||||
;; This file 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 3, or (at your
|
||||
;; option) any later version.
|
||||
;;
|
||||
;; This file 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.
|
||||
;;
|
||||
;; For a full copy of the GNU General Public License
|
||||
;; see <http://www.gnu.org/licenses/>.
|
||||
|
||||
;;; Commentary:
|
||||
;;
|
||||
;; Blacken uses black to format a Python buffer. It can be called
|
||||
;; explicitly on a certain buffer, but more conveniently, a minor-mode
|
||||
;; 'blacken-mode' is provided that turns on automatically running
|
||||
;; black on a buffer before saving.
|
||||
;;
|
||||
;; Installation:
|
||||
;;
|
||||
;; Add blacken.el to your load-path.
|
||||
;;
|
||||
;; To automatically format all Python buffers before saving, add the
|
||||
;; function blacken-mode to python-mode-hook:
|
||||
;;
|
||||
;; (add-hook 'python-mode-hook 'blacken-mode)
|
||||
;;
|
||||
;;; Code:
|
||||
|
||||
|
||||
(defgroup blacken nil
|
||||
"Reformat Python code with \"black\"."
|
||||
:group 'python)
|
||||
|
||||
(defcustom blacken-executable "black"
|
||||
"Name of the executable to run."
|
||||
:type 'string)
|
||||
|
||||
(defcustom blacken-line-length nil
|
||||
"Line length to enforce."
|
||||
:type 'number
|
||||
:safe 'numberp)
|
||||
|
||||
(defun blacken-call-bin (input-buffer output-buffer error-buffer)
|
||||
"Call process black.
|
||||
|
||||
Send INPUT-BUFFER content to the process stdin. Saving the
|
||||
output to OUTPUT-BUFFER. Saving process stderr to ERROR-BUFFER.
|
||||
Return black process the exit code."
|
||||
(with-current-buffer input-buffer
|
||||
(let ((process (make-process :name "blacken"
|
||||
:command `(,blacken-executable ,@(blacken-call-args))
|
||||
:buffer output-buffer
|
||||
:stderr error-buffer
|
||||
:noquery t
|
||||
:sentinel (lambda (process event)))))
|
||||
(set-process-query-on-exit-flag (get-buffer-process error-buffer) nil)
|
||||
(set-process-sentinel (get-buffer-process error-buffer) (lambda (process event)))
|
||||
(save-restriction
|
||||
(widen)
|
||||
(process-send-region process (point-min) (point-max)))
|
||||
(process-send-eof process)
|
||||
(accept-process-output process nil nil t)
|
||||
(while (process-live-p process)
|
||||
(accept-process-output process nil nil t))
|
||||
(process-exit-status process))))
|
||||
|
||||
(defun blacken-call-args ()
|
||||
"Build black process call arguments."
|
||||
(append
|
||||
(when blacken-line-length
|
||||
(list "--line-length" (number-to-string blacken-line-length)))
|
||||
'("-")))
|
||||
|
||||
;;;###autoload
|
||||
(defun blacken-buffer (&optional display)
|
||||
"Try to blacken the current buffer.
|
||||
|
||||
Show black output, if black exit abnormally and DISPLAY is t."
|
||||
(interactive (list t))
|
||||
(let* ((original-buffer (current-buffer))
|
||||
(original-point (point))
|
||||
(original-window-pos (window-start))
|
||||
(tmpbuf (get-buffer-create "*blacken*"))
|
||||
(errbuf (get-buffer-create "*blacken-error*")))
|
||||
;; This buffer can be left after previous black invocation. It
|
||||
;; can contain error message of the previous run.
|
||||
(dolist (buf (list tmpbuf errbuf))
|
||||
(with-current-buffer buf
|
||||
(erase-buffer)))
|
||||
(condition-case err
|
||||
(if (not (zerop (blacken-call-bin original-buffer tmpbuf errbuf)))
|
||||
(error "Black failed, see %s buffer for details" (buffer-name errbuf))
|
||||
(with-current-buffer tmpbuf
|
||||
(copy-to-buffer original-buffer (point-min) (point-max)))
|
||||
(mapc 'kill-buffer (list tmpbuf errbuf))
|
||||
(goto-char original-point)
|
||||
(set-window-start (selected-window) original-window-pos))
|
||||
(error (message "%s" (error-message-string err))
|
||||
(when display
|
||||
(pop-to-buffer errbuf))))))
|
||||
|
||||
;;;###autoload
|
||||
(define-minor-mode blacken-mode
|
||||
"Automatically run black before saving."
|
||||
:lighter " Black"
|
||||
(if blacken-mode
|
||||
(add-hook 'before-save-hook 'blacken-buffer nil t)
|
||||
(remove-hook 'before-save-hook 'blacken-buffer t)))
|
||||
|
||||
(provide 'blacken)
|
||||
|
||||
;;; blacken.el ends here
|
||||
Loading…
Add table
Add a link
Reference in a new issue