Skip to content

Commit 668069a

Browse files
kovanclaude
andauthored
feat: improve rust-toggle-mutability to handle references (#584)
* feat: improve rust-toggle-mutability to handle references Extends `rust-toggle-mutability` to handle `&` <-> `&mut` and `&self` <-> `&mut self` in addition to `let` <-> `let mut`. Closes #194 Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> * test: add tests for rust-toggle-mutability Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
1 parent f68ddca commit 668069a

2 files changed

Lines changed: 65 additions & 6 deletions

File tree

rust-mode-tests.el

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3809,3 +3809,39 @@ let b = 1;"
38093809
(string-match "^C-c C" ,match)))
38103810
t))
38113811
(should (< 0 match-count)))))
3812+
3813+
;; Toggle mutability tests
3814+
3815+
(ert-deftest rust-toggle-mutability-let ()
3816+
"Test toggling let <-> let mut."
3817+
(with-temp-buffer
3818+
(rust-mode)
3819+
(insert " let x = 5;")
3820+
(rust-toggle-mutability)
3821+
(should (string= (buffer-string) " let mut x = 5;"))
3822+
(rust-toggle-mutability)
3823+
(should (string= (buffer-string) " let x = 5;"))))
3824+
3825+
(ert-deftest rust-toggle-mutability-ref ()
3826+
"Test toggling & <-> &mut."
3827+
(with-temp-buffer
3828+
(rust-mode)
3829+
(insert " let y = & x;")
3830+
(goto-char (line-end-position))
3831+
(rust-toggle-mutability)
3832+
(should (string-match-p "&mut " (buffer-string)))
3833+
(goto-char (line-end-position))
3834+
(rust-toggle-mutability)
3835+
(should (string-match-p "& x" (buffer-string)))))
3836+
3837+
(ert-deftest rust-toggle-mutability-self ()
3838+
"Test toggling &self <-> &mut self."
3839+
(with-temp-buffer
3840+
(rust-mode)
3841+
(insert " fn foo(&self) {")
3842+
(goto-char (line-end-position))
3843+
(rust-toggle-mutability)
3844+
(should (string-match-p "&mut self" (buffer-string)))
3845+
(goto-char (line-end-position))
3846+
(rust-toggle-mutability)
3847+
(should (string-match-p "&self" (buffer-string)))))

rust-utils.el

Lines changed: 29 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -108,15 +108,38 @@ if not. Move cursor to the end of macro."
108108
)
109109
)
110110

111+
;;;###autoload
111112
(defun rust-toggle-mutability ()
112-
"Toggles the mutability of the variable defined on the current line"
113+
"Toggle the mutability of the binding or reference near point.
114+
Handles `let' <-> `let mut' and `&' <-> `&mut' (including `&self')."
113115
(interactive)
114116
(save-excursion
115-
(back-to-indentation)
116-
(forward-word)
117-
(if (string= " mut" (buffer-substring (point) (+ (point) 4)))
118-
(delete-region (point) (+ (point) 4))
119-
(insert " mut"))))
117+
(let ((line-start (line-beginning-position))
118+
(line-end (line-end-position)))
119+
(cond
120+
;; Remove: &mut -> &
121+
((search-backward "&mut " line-start t)
122+
(forward-char 1)
123+
(delete-region (point) (+ (point) 4)))
124+
;; Remove: let mut -> let
125+
((progn (goto-char (line-beginning-position))
126+
(re-search-forward "\\_<let mut\\_>" line-end t))
127+
(replace-match "let"))
128+
;; Add: & -> &mut
129+
((progn (goto-char (line-end-position))
130+
(search-backward "& " line-start t))
131+
(forward-char 1)
132+
(insert "mut "))
133+
;; Add: &self -> &mut self
134+
((progn (goto-char (line-end-position))
135+
(search-backward "&self" line-start t))
136+
(forward-char 1)
137+
(insert "mut "))
138+
;; Add: let -> let mut
139+
((progn (goto-char (line-beginning-position))
140+
(re-search-forward "\\_<let\\_>" line-end t))
141+
(insert " mut"))
142+
(t (message "No mutable/immutable binding or reference found on this line"))))))
120143
;;; _
121144
(provide 'rust-utils)
122145
;;; rust-utils.el ends here

0 commit comments

Comments
 (0)