-
Notifications
You must be signed in to change notification settings - Fork 195
Expand file tree
/
Copy pathrust-utils.el
More file actions
145 lines (127 loc) · 4.46 KB
/
rust-utils.el
File metadata and controls
145 lines (127 loc) · 4.46 KB
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
;;; rust-utils.el --- Various Rust utilities -*- lexical-binding:t -*-
;;; Commentary:
;; This library implements various utilities for dealing with Rust
;; code.
;;; Code:
(require 'thingatpt)
(require 'rust-mode) ; for `rust-in-str' and `rust-looking-back-str'
;;; Promote module
(defun rust-promote-module-into-dir ()
"Promote the module file visited by the current buffer into its own directory.
For example, if the current buffer is visiting the file `foo.rs',
then this function creates the directory `foo' and renames the
file to `foo/mod.rs'. The current buffer will be updated to
visit the new file."
(interactive)
(let ((filename (buffer-file-name)))
(if (not filename)
(message "Buffer is not visiting a file.")
(if (string-equal (file-name-nondirectory filename) "mod.rs")
(message "Won't promote a module file already named mod.rs.")
(let* ((basename (file-name-sans-extension
(file-name-nondirectory filename)))
(mod-dir (file-name-as-directory
(concat (file-name-directory filename) basename)))
(new-name (concat mod-dir "mod.rs")))
(mkdir mod-dir t)
(rename-file filename new-name 1)
(set-visited-file-name new-name))))))
;;; dbg! macro
(defun rust-insert-dbg-sexp ()
"Insert the dbg! macro around a sexp if possible, insert at current position
if not. Move cursor to the end of macro."
(when (rust-in-str)
(up-list -1 t t))
(let ((safe-to-forward t))
(save-excursion
(condition-case nil
(forward-sexp)
(error (setq safe-to-forward nil)
nil)))
(cond
((not safe-to-forward)
(rust-insert-dbg-alone))
(t
(insert "(")
(forward-sexp)
(insert ")")
(backward-sexp)
(insert "dbg!")
(forward-sexp)))))
(defun rust-insert-dbg-region ()
"Insert the dbg! macro around a region. Move cursor to the end of macro."
(when (< (mark) (point))
(exchange-point-and-mark))
(let ((old-point (point)))
(insert-parentheses)
(goto-char old-point))
(insert "dbg!")
(forward-sexp))
(defun rust-insert-dbg-alone ()
"Insert the dbg! macro alone. Move cursor in between the brackets."
(insert "dbg!()")
(backward-char))
;;;###autoload
(defun rust-dbg-wrap-or-unwrap ()
"Either remove or add the dbg! macro."
(interactive)
(cond
;; region
((region-active-p)
(rust-insert-dbg-region))
;; alone
((or (looking-at-p " *$") (looking-at-p " *//.*"))
(rust-insert-dbg-alone))
;; symbol
(t
(let ((beginning-of-symbol (ignore-errors (beginning-of-thing 'symbol))))
(when beginning-of-symbol
(goto-char beginning-of-symbol)))
(let ((dbg-point (save-excursion
(or (and (looking-at-p "dbg!") (+ 4 (point)))
(ignore-errors
(while (not (rust-looking-back-str "dbg!"))
(backward-up-list))
(point))))))
(cond (dbg-point
(goto-char dbg-point)
(delete-char -4)
(delete-pair))
(t (rust-insert-dbg-sexp)))))
)
)
;;;###autoload
(defun rust-toggle-mutability ()
"Toggle the mutability of the binding or reference near point.
Handles `let' <-> `let mut' and `&' <-> `&mut' (including `&self')."
(interactive)
(save-excursion
(let ((line-start (line-beginning-position))
(line-end (line-end-position)))
(cond
;; Remove: &mut -> &
((search-backward "&mut " line-start t)
(forward-char 1)
(delete-region (point) (+ (point) 4)))
;; Remove: let mut -> let
((progn (goto-char (line-beginning-position))
(re-search-forward "\\_<let mut\\_>" line-end t))
(replace-match "let"))
;; Add: & -> &mut
((progn (goto-char (line-end-position))
(search-backward "& " line-start t))
(forward-char 1)
(insert "mut "))
;; Add: &self -> &mut self
((progn (goto-char (line-end-position))
(search-backward "&self" line-start t))
(forward-char 1)
(insert "mut "))
;; Add: let -> let mut
((progn (goto-char (line-beginning-position))
(re-search-forward "\\_<let\\_>" line-end t))
(insert " mut"))
(t (message "No mutable/immutable binding or reference found on this line"))))))
;;; _
(provide 'rust-utils)
;;; rust-utils.el ends here