@@ -181,6 +181,15 @@ function or trait. When nil, where will be aligned with fn or trait."
181
181
:safe #'booleanp
182
182
:group 'rust-mode )
183
183
184
+ (defcustom rust-format-on-save nil
185
+ " Format future rust buffers before saving using rustfmt."
186
+ :type 'boolean
187
+ :safe #'booleanp )
188
+
189
+ (defcustom rust-rustfmt-bin " rustfmt"
190
+ " Path to rustfmt executable."
191
+ :type 'string )
192
+
184
193
(defface rust-unsafe-face
185
194
'((t :inherit font-lock-warning-face ))
186
195
" Face for the `unsafe' keyword."
@@ -1211,13 +1220,55 @@ This is written mainly to be used as `end-of-defun-function' for Rust."
1211
1220
; ; There is no opening brace, so consider the whole buffer to be one "defun"
1212
1221
(goto-char (point-max ))))
1213
1222
1223
+ ; ; Formatting using rustfmt
1224
+ (defun rust--format-call (buf )
1225
+ " Format BUF using rustfmt."
1226
+ (with-current-buffer (get-buffer-create " *rustfmt*" )
1227
+ (erase-buffer )
1228
+ (insert-buffer-substring buf)
1229
+ (if (zerop (call-process-region (point-min ) (point-max ) rust-rustfmt-bin t t nil ))
1230
+ (progn (copy-to-buffer buf (point-min ) (point-max ))
1231
+ (kill-buffer ))
1232
+ (error " Rustfmt failed, see *rustfmt* buffer for details " ))))
1233
+
1234
+ (defun rust-format-buffer ()
1235
+ " Format the current buffer using rustfmt."
1236
+ (interactive )
1237
+ (unless (executable-find rust-rustfmt-bin)
1238
+ (error " Could not locate executable \" %s \" " rust-rustfmt-bin))
1239
+
1240
+ (let ((cur-point (point ))
1241
+ (cur-win-start (window-start )))
1242
+ (rust--format-call (current-buffer ))
1243
+ (goto-char cur-point)
1244
+ (set-window-start (selected-window ) cur-win-start))
1245
+ (message " Formatted buffer with rustfmt. " ))
1246
+
1247
+ (defun rust-enable-format-on-save ()
1248
+ " Enable formatting using rustfmt when saving buffer."
1249
+ (interactive )
1250
+ (add-hook 'before-save-hook #'rust-format-buffer nil t ))
1251
+
1252
+ (defun rust-disable-format-on-save ()
1253
+ " Disable formatting using rustfmt when saving buffer."
1254
+ (interactive )
1255
+ (remove-hook 'before-save-hook #'rust-format-buffer t ))
1256
+
1214
1257
; ; For compatibility with Emacs < 24, derive conditionally
1215
1258
(defalias 'rust-parent-mode
1216
1259
(if (fboundp 'prog-mode ) 'prog-mode 'fundamental-mode ))
1217
1260
1261
+ (defvar rust-mode-map
1262
+ (let ((map (make-sparse-keymap )))
1263
+ (define-key map (kbd " C-c C-f" ) 'rust-format-buffer )
1264
+ map)
1265
+ " Keymap for Rust major mode." )
1266
+
1218
1267
;;;### autoload
1219
1268
(define-derived-mode rust-mode rust-parent-mode " Rust"
1220
- " Major mode for Rust code."
1269
+ " Major mode for Rust code.
1270
+
1271
+ \\ {rust-mode-map}"
1221
1272
:group 'rust-mode
1222
1273
:syntax-table rust-mode-syntax-table
1223
1274
@@ -1255,7 +1306,9 @@ This is written mainly to be used as `end-of-defun-function' for Rust."
1255
1306
(setq-local parse-sexp-lookup-properties t )
1256
1307
(setq-local electric-pair-inhibit-predicate 'rust-electric-pair-inhibit-predicate-wrap )
1257
1308
(add-hook 'after-revert-hook 'rust--after-revert-hook 'LOCAL )
1258
- )
1309
+
1310
+ (when rust-format-on-save
1311
+ (rust-enable-format-on-save)))
1259
1312
1260
1313
;;;### autoload
1261
1314
(add-to-list 'auto-mode-alist '(" \\ .rs\\ '" . rust-mode))
0 commit comments