|
|
- ;;; yapfify.el --- (automatically) format python buffers using YAPF.
-
- ;; Copyright (C) 2016 Joris Engbers
-
- ;; Author: Joris Engbers <info@jorisengbers.nl>
- ;; Homepage: https://github.com/JorisE/yapfify
- ;; Version: 0.0.6
- ;; Package-Version: 20180830.733
- ;; Package-Requires: ()
-
- ;; 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:
- ;;
- ;; Yapfify uses yapf to format a Python buffer. It can be called explicitly on a
- ;; certain buffer, but more conveniently, a minor-mode 'yapf-mode' is provided
- ;; that turns on automatically running YAPF on a buffer before saving.
- ;;
- ;; Installation:
- ;;
- ;; Add yapfify.el to your load-path.
- ;;
- ;; To automatically format all Python buffers before saving, add the function
- ;; yapf-mode to python-mode-hook:
- ;;
- ;; (add-hook 'python-mode-hook 'yapf-mode)
- ;;
- ;;; Code:
-
- (require 'cl)
-
- (defun yapfify-call-bin (input-buffer output-buffer start-line end-line)
- "Call process yapf on INPUT-BUFFER saving the output to OUTPUT-BUFFER.
-
- Return the exit code. START-LINE and END-LINE specify region to
- format."
- (with-current-buffer input-buffer
- (call-process-region (point-min) (point-max) "yapf" nil output-buffer nil "-l" (concat (number-to-string start-line) "-" (number-to-string end-line)))))
-
- (defun get-buffer-string (buffer)
- "Return the contents of BUFFER."
- (with-current-buffer buffer
- (buffer-string)))
-
- ;;;###autoload
- (defun yapfify-region (beginning end)
- "Try to yapfify the current region.
-
- If yapf exits with an error, the output will be shown in a help-window."
- (interactive "r")
- (let* ((original-buffer (current-buffer))
- (original-point (point)) ; Because we are replacing text, save-excursion does not always work.
- (buffer-windows (get-buffer-window-list original-buffer nil t))
- (original-window-pos (mapcar 'window-start buffer-windows))
- (start-line (line-number-at-pos beginning))
- (end-line (line-number-at-pos (if (or (= (char-before end) 10)
- (= (char-before end) 13))
- (- end 1)
- end)))
- (tmpbuf (generate-new-buffer "*yapfify*"))
- (exit-code (yapfify-call-bin original-buffer tmpbuf start-line end-line)))
- (deactivate-mark)
- ;; There are three exit-codes defined for YAPF:
- ;; 0: Exit with success (change or no change on yapf >=0.11)
- ;; 1: Exit with error
- ;; 2: Exit with success and change (Backward compatibility)
- ;; anything else would be very unexpected.
- (cond ((or (eq exit-code 0) (eq exit-code 2))
- (with-current-buffer tmpbuf
- (copy-to-buffer original-buffer (point-min) (point-max))))
- ((eq exit-code 1)
- (error "Yapf failed, see %s buffer for details" (buffer-name tmpbuf))))
- ;; Clean up tmpbuf
- (kill-buffer tmpbuf)
- ;; restore window to similar state
- (goto-char original-point)
- (mapcar* 'set-window-start buffer-windows original-window-pos)))
-
- ;;;###autoload
- (defun yapfify-buffer ()
- "Yapfify whole buffer."
- (interactive)
- (yapfify-region (point-min) (point-max)))
-
- ;;;###autoload
- (define-minor-mode yapf-mode
- "Automatically run YAPF before saving."
- :lighter " YAPF"
- (if yapf-mode
- (add-hook 'before-save-hook 'yapfify-buffer nil t)
- (remove-hook 'before-save-hook 'yapfify-buffer t)))
-
- (provide 'yapfify)
-
- ;;; yapfify.el ends here
|