diff options
Diffstat (limited to 'emacs.d/elpa/blacken-20191123.1547/blacken.el')
-rw-r--r-- | emacs.d/elpa/blacken-20191123.1547/blacken.el | 176 |
1 files changed, 176 insertions, 0 deletions
diff --git a/emacs.d/elpa/blacken-20191123.1547/blacken.el b/emacs.d/elpa/blacken-20191123.1547/blacken.el new file mode 100644 index 0000000..ded35e0 --- /dev/null +++ b/emacs.d/elpa/blacken-20191123.1547/blacken.el @@ -0,0 +1,176 @@ +;;; blacken.el --- Reformat python buffers using the "black" formatter + +;; Copyright (C) 2018-2019 Artem Malyshev + +;; Author: Artem Malyshev <proofit404@gmail.com> +;; Homepage: https://github.com/proofit404/blacken +;; Version: 0.0.1 +;; Package-Version: 20191123.1547 +;; 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: + +(require 'cl-lib) + +(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. + +It must be an integer, nil or `fill'. +If `fill', the `fill-column' variable value is used." + :type '(choice :tag "Line Length Limit" + (const :tag "Use default" nil) + (const :tag "Use fill-column" fill) + (integer :tag "Line Length")) + :safe 'integerp) + +(defcustom blacken-allow-py36 nil + "Allow using Python 3.6-only syntax on all input files." + :type 'boolean + :safe 'booleanp) + +(defcustom blacken-skip-string-normalization nil + "Don't normalize string quotes or prefixes." + :type 'boolean + :safe 'booleanp) + +(defcustom blacken-fast-unsafe nil + "Skips temporary sanity checks." + :type 'boolean + :safe 'booleanp) + +(defcustom blacken-only-if-project-is-blackened nil + "Only blacken if project has a pyproject.toml with a [tool.black] section." + :type 'boolean + :safe 'booleanp) + +(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 (cl-case blacken-line-length + ('fill fill-column) + (t blacken-line-length))))) + (when blacken-allow-py36 + (list "--py36")) + (when blacken-fast-unsafe + (list "--fast")) + (when blacken-skip-string-normalization + (list "--skip-string-normalization")) + (when (and (buffer-file-name (current-buffer)) + (string-match "\.pyi$" (buffer-file-name (current-buffer)))) + (list "--pyi")) + '("-"))) + +(defun blacken-project-is-blackened (&optional display) + "Whether the project has a pyproject.toml with [tool.black] in it." + (when-let ((parent (locate-dominating-file default-directory "pyproject.toml"))) + (with-temp-buffer + (insert-file-contents (concat parent "pyproject.toml")) + (re-search-forward "^\\[tool.black\\]$" nil t 1)))) + +;;;###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)) + (unless (eq (compare-buffer-substrings tmpbuf nil nil original-buffer nil nil) 0) + (with-current-buffer tmpbuf + (copy-to-buffer original-buffer (point-min) (point-max))) + (goto-char original-point) + (set-window-start (selected-window) original-window-pos)) + (mapc 'kill-buffer (list tmpbuf errbuf))) + (error (message "%s" (error-message-string err)) + (when display + (with-current-buffer errbuf + (setq-local scroll-conservatively 0)) + (pop-to-buffer errbuf)))))) + +;;;###autoload +(define-minor-mode blacken-mode + "Automatically run black before saving." + :lighter " Black" + (if blacken-mode + (when (or (not blacken-only-if-project-is-blackened) + (blacken-project-is-blackened)) + (add-hook 'before-save-hook 'blacken-buffer nil t)) + (remove-hook 'before-save-hook 'blacken-buffer t))) + +(provide 'blacken) + +;;; blacken.el ends here |