forked from rust-lang/rust-mode
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathrust-cargo.el
103 lines (80 loc) · 2.76 KB
/
rust-cargo.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
;;; rust-cargo.el --- Support for cargo -*-lexical-binding: t-*-
;;; Commentary:
;; This library implements support for running `cargo'.
;;; Code:
(require 'json)
;;; Options
(defcustom rust-cargo-bin "cargo"
"Path to cargo executable."
:type 'string
:group 'rust-mode)
(defcustom rust-always-locate-project-on-open nil
"Whether to run `cargo locate-project' every time `rust-mode' is activated."
:type 'boolean
:group 'rust-mode)
;;; Buffer Project
(defvar-local rust-buffer-project nil)
(defun rust-buffer-project ()
"Get project root if possible."
(with-temp-buffer
(let ((ret (call-process rust-cargo-bin nil t nil "locate-project")))
(when (/= ret 0)
(error "`cargo locate-project' returned %s status: %s" ret (buffer-string)))
(goto-char 0)
(let ((output (json-read)))
(cdr (assoc-string "root" output))))))
(defun rust-update-buffer-project ()
(setq-local rust-buffer-project (rust-buffer-project)))
(defun rust-maybe-initialize-buffer-project ()
(setq-local rust-buffer-project nil)
(when rust-always-locate-project-on-open
(rust-update-buffer-project)))
(add-hook 'rust-mode-hook 'rust-maybe-initialize-buffer-project)
;;; Internal
(defun rust--compile (format-string &rest args)
(when (null rust-buffer-project)
(rust-update-buffer-project))
(let ((default-directory
(or (and rust-buffer-project
(file-name-directory rust-buffer-project))
default-directory)))
(compile (apply #'format format-string args))))
;;; Commands
(defun rust-check ()
"Compile using `cargo check`"
(interactive)
(rust--compile "%s check" rust-cargo-bin))
(defun rust-compile ()
"Compile using `cargo build`"
(interactive)
(rust--compile "%s build" rust-cargo-bin))
(defun rust-compile-release ()
"Compile using `cargo build --release`"
(interactive)
(rust--compile "%s build --release" rust-cargo-bin))
(defun rust-run ()
"Run using `cargo run`"
(interactive)
(rust--compile "%s run" rust-cargo-bin))
(defun rust-run-release ()
"Run using `cargo run --release`"
(interactive)
(rust--compile "%s run --release" rust-cargo-bin))
(defun rust-test ()
"Test using `cargo test`"
(interactive)
(rust--compile "%s test" rust-cargo-bin))
(defun rust-run-clippy ()
"Run `cargo clippy'."
(interactive)
(when (null rust-buffer-project)
(rust-update-buffer-project))
(let* ((args (list rust-cargo-bin "clippy"
(concat "--manifest-path=" rust-buffer-project)))
;; set `compile-command' temporarily so `compile' doesn't
;; clobber the existing value
(compile-command (mapconcat #'shell-quote-argument args " ")))
(rust--compile compile-command)))
;;; _
(provide 'rust-cargo)
;;; rust-cargo.el ends here