forked from pythonic-emacs/isortify
-
Notifications
You must be signed in to change notification settings - Fork 0
/
isortify.el
113 lines (98 loc) · 4 KB
/
isortify.el
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
;;; isortify.el --- (automatically) format python buffers using isort.
;; Copyright (C) 2016-2018 Artem Malyshev
;; Author: Artem Malyshev <[email protected]>
;; Homepage: https://github.com/proofit404/isortify
;; Version: 0.0.1
;; 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:
;;
;; Isortify uses isort to format a Python buffer. It can be called
;; explicitly on a certain buffer, but more conveniently, a minor-mode
;; 'isortify-mode' is provided that turns on automatically running isort
;; on a buffer before saving.
;;
;; Installation:
;;
;; Add isortify.el to your load-path.
;;
;; To automatically format all Python buffers before saving, add the function
;; isortify-mode to python-mode-hook:
;;
;; (add-hook 'python-mode-hook 'isortify-mode)
;;
;;; Code:
(defvar isortify-multi-line-output nil)
(defvar isortify-trailing-comma nil)
(defvar isortify-known-first-party nil)
(defvar isortify-lines-after-imports nil)
(defun isortify-call-bin (input-buffer output-buffer)
"Call process isort on INPUT-BUFFER saving the output to OUTPUT-BUFFER.
Return isort process the exit code."
(with-current-buffer input-buffer
(let (args)
(when isortify-multi-line-output
(push "--multi-line" args)
(push (number-to-string isortify-multi-line-output) args))
(when isortify-trailing-comma
(push "--trailing-comma" args))
(when isortify-known-first-party
(dolist (project isortify-known-first-party)
(push "--project" args)
(push project args)))
(when isortify-lines-after-imports
(push "--lines-after-imports" args)
(push (number-to-string isortify-lines-after-imports) args))
(push "-" args)
(let ((process (apply 'start-file-process "isortify" output-buffer "isort" (reverse args))))
(set-process-sentinel process (lambda (process event)))
(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)))))
;;;###autoload
(defun isortify-buffer (&optional display)
"Try to isortify the current buffer.
Show isort output, if isort 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 "*isortify*")))
;; This buffer can be left after previous isort invocation. It
;; can contain error message of the previous run.
(with-current-buffer tmpbuf
(erase-buffer))
(condition-case err
(if (not (zerop (isortify-call-bin original-buffer tmpbuf)))
(error "Isort failed, see %s buffer for details" (buffer-name tmpbuf))
(with-current-buffer tmpbuf
(copy-to-buffer original-buffer (point-min) (point-max)))
(kill-buffer tmpbuf)
(goto-char original-point)
(set-window-start (selected-window) original-window-pos))
(error (message "%s" (error-message-string err))
(when display
(pop-to-buffer tmpbuf))))))
;;;###autoload
(define-minor-mode isortify-mode
"Automatically run isort before saving."
:lighter " Isort"
(if isortify-mode
(add-hook 'before-save-hook 'isortify-buffer nil t)
(remove-hook 'before-save-hook 'isortify-buffer t)))
(provide 'isortify)
;;; isortify.el ends here