Skip to content

Commit 86c55b1

Browse files
committed
Integrate rustfmt support
Merges the rustfmt package (https://github.com/fbergroth/rust-mode) Fixes #120.
1 parent fa5b38f commit 86c55b1

File tree

1 file changed

+55
-2
lines changed

1 file changed

+55
-2
lines changed

rust-mode.el

Lines changed: 55 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -181,6 +181,15 @@ function or trait. When nil, where will be aligned with fn or trait."
181181
:safe #'booleanp
182182
:group 'rust-mode)
183183

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+
184193
(defface rust-unsafe-face
185194
'((t :inherit font-lock-warning-face))
186195
"Face for the `unsafe' keyword."
@@ -1211,13 +1220,55 @@ This is written mainly to be used as `end-of-defun-function' for Rust."
12111220
;; There is no opening brace, so consider the whole buffer to be one "defun"
12121221
(goto-char (point-max))))
12131222

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+
12141257
;; For compatibility with Emacs < 24, derive conditionally
12151258
(defalias 'rust-parent-mode
12161259
(if (fboundp 'prog-mode) 'prog-mode 'fundamental-mode))
12171260

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+
12181267
;;;###autoload
12191268
(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}"
12211272
:group 'rust-mode
12221273
:syntax-table rust-mode-syntax-table
12231274

@@ -1255,7 +1306,9 @@ This is written mainly to be used as `end-of-defun-function' for Rust."
12551306
(setq-local parse-sexp-lookup-properties t)
12561307
(setq-local electric-pair-inhibit-predicate 'rust-electric-pair-inhibit-predicate-wrap)
12571308
(add-hook 'after-revert-hook 'rust--after-revert-hook 'LOCAL)
1258-
)
1309+
1310+
(when rust-format-on-save
1311+
(rust-enable-format-on-save)))
12591312

12601313
;;;###autoload
12611314
(add-to-list 'auto-mode-alist '("\\.rs\\'" . rust-mode))

0 commit comments

Comments
 (0)