-
Notifications
You must be signed in to change notification settings - Fork 3
/
Copy pathdfmt.el
162 lines (140 loc) · 5.1 KB
/
dfmt.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
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
;;; dfmt.el --- Emacs Interface to D indenting/formatting tool dfmt.
;; Author: Per Nordlöw
;; Contributors: Kirill Babikhin
;; Maintainer: Kirill Babikhin <qsimpleq>
;; Keywords: tools, convenience, languages, Dlang
;; URL: https://github.com/qsimpleq/elisp-dfmt
;; Version: 0.1.0
;; License: GPL v2, or any later version
;;; Commentary:
;; Original version: https://github.com/nordlow/elisp/blob/master/mine/dfmt.el
;; Enable hotkeys
;; (add-hook 'd-mode-hook 'dfmt-setup-keys)
;;; Code:
(defgroup dfmt nil
"Interface to D dfmt."
:group 'tools)
(defcustom dfmt-command "dfmt" "D format command"
:group 'dfmt)
(defcustom dfmt-flags
'()
"Flags sent to dfmt."
:type 'list
:group 'dfmt)
(defcustom dfmt-command "dfmt" "D format command"
:group 'dfmt)
(defvar dfmt-buffer-name "*dfmt*"
"*Name of the temporary dfmt buffer.")
(defvar dfmt-stderr-buffer-name "*dfmt-stderr*"
"*Name of the temporary dfmt buffer.")
(defvar dfmt-stderr-verbose t "Verbose error message")
(defvar dfmt-stderr-begin-message "Cannot format buffer, please check your code")
;;;###autoload
(defun dfmt-region (beg end)
"Format D BUFFER's region from START to END using the external
D formatting program dfmt."
(interactive "r")
(if (executable-find dfmt-command)
(let ((outfile (expand-file-name dfmt-buffer-name temporary-file-directory))
(errfile (expand-file-name dfmt-stderr-buffer-name temporary-file-directory))
(outbuffer (get-buffer-create dfmt-buffer-name))
(errbuffer (get-buffer-create dfmt-stderr-buffer-name))
(errmsg)
(d-mode-buffer (current-buffer))
(old-point (point))
)
(set-buffer outbuffer)
(erase-buffer)
(set-buffer errbuffer)
(erase-buffer)
(set-buffer d-mode-buffer)
(apply #'call-process-region
(append (list beg end dfmt-command
nil
(list dfmt-buffer-name errfile)
nil
)
dfmt-flags))
(if (> (nth 7 (file-attributes errfile))
0)
(progn
(if dfmt-stderr-verbose
(setq errmsg (concat dfmt-stderr-begin-message ":\n"
(with-temp-buffer
(insert-file-contents errfile)
(buffer-string))))
(setq errmsg dfmt-stderr-begin-message))
(set-buffer errbuffer)
(insert errmsg)
(delete-file errfile)
(message "%s" errmsg)
nil)
(progn
(delete-region beg end)
(goto-char beg)
(insert-buffer-substring outbuffer)
(goto-char old-point)
(font-lock-fontify-buffer)
t)))
(error "Seem dfmt is not installed")))
(defalias 'd-indent-region 'dfmt-region)
;;;###autoload
(defun dfmt-buffer ()
"Format D Buffer using the external D formatting program dfmt."
(interactive)
(dfmt-region (point-min) (point-max)))
(defalias 'd-indent-buffer 'dfmt-buffer)
;;;###autoload
(defun dfmt-region-or-buffer ()
"Indent a region if selected, otherwise the whole buffer."
(interactive)
(let ((buf (current-buffer))
beg end)
(if (region-active-p)
(progn
(setq beg (region-beginning)
end (region-end))
(dfmt-region beg end))
(dfmt-buffer))
)
)
(defalias 'd-indent-region-or-buffer 'dfmt-region-or-buffer)
;;;###autoload
(defun dfmt-file (file out-file)
"Format D Source or Header FILE using the external program dfmt and put result in OUT-FILE."
(interactive "fFormat source file: \nFOutput file (from format): ")
(when (executable-find dfmt-command)
(progn (apply #'call-process
(append (list dfmt-command
file
`(:file ,out-file)
t
)
dfmt-flags))
(find-file out-file))))
(defalias 'd-indent-file 'dfmt-file)
;;;###autoload
(defun dfmt-save-buffer ()
"Format D Buffer using the external D formatting program dfmt and
save current buffer in visited file if modified.
You are will can't to save a brokened dlang code."
(interactive)
(when (buffer-modified-p)
(if (dfmt-buffer)
(save-buffer)
(error (with-temp-buffer
(insert-buffer-substring (get-buffer dfmt-stderr-buffer-name))
(buffer-string))))))
;;;###autoload
(defun dfmt-setup-keys ()
(local-set-key [(control c) (F) (r)] 'dfmt-region)
(local-set-key [(control c) (F) (b)] 'dfmt-buffer)
(local-set-key [(control c) (F) (f)] 'dfmt-file))
(define-key menu-bar-tools-menu [dfmt-buffer]
'(menu-item "Tidy D Buffer (dfmt)..." dfmt-buffer
:help "Format a D source buffer using dfmt"))
(define-key menu-bar-tools-menu [dfmt-file]
'(menu-item "Tidy D File (dfmt)..." dfmt-file
:help "Format a D source file using dfmt"))
(provide 'dfmt)
;;; dfmt.el ends here