branch: elpa/rust-mode
commit 668069ad8b6ca20bd0d2334db1c0d046809affd6
Author: kovan <[email protected]>
Commit: GitHub <[email protected]>

    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 <[email protected]>
    
    * test: add tests for rust-toggle-mutability
    
    Co-authored-by: Claude Opus 4.6 <[email protected]>
    
    ---------
    
    Co-authored-by: Claude Opus 4.6 <[email protected]>
---
 rust-mode-tests.el | 36 ++++++++++++++++++++++++++++++++++++
 rust-utils.el      | 35 +++++++++++++++++++++++++++++------
 2 files changed, 65 insertions(+), 6 deletions(-)

diff --git a/rust-mode-tests.el b/rust-mode-tests.el
index 259afb2888..4c970c43b8 100644
--- a/rust-mode-tests.el
+++ b/rust-mode-tests.el
@@ -3809,3 +3809,39 @@ let b = 1;"
             (string-match "^C-c C" ,match)))
          t))
       (should (< 0 match-count)))))
+
+;; Toggle mutability tests
+
+(ert-deftest rust-toggle-mutability-let ()
+  "Test toggling let <-> let mut."
+  (with-temp-buffer
+    (rust-mode)
+    (insert "    let x = 5;")
+    (rust-toggle-mutability)
+    (should (string= (buffer-string) "    let mut x = 5;"))
+    (rust-toggle-mutability)
+    (should (string= (buffer-string) "    let x = 5;"))))
+
+(ert-deftest rust-toggle-mutability-ref ()
+  "Test toggling & <-> &mut."
+  (with-temp-buffer
+    (rust-mode)
+    (insert "    let y = & x;")
+    (goto-char (line-end-position))
+    (rust-toggle-mutability)
+    (should (string-match-p "&mut " (buffer-string)))
+    (goto-char (line-end-position))
+    (rust-toggle-mutability)
+    (should (string-match-p "& x" (buffer-string)))))
+
+(ert-deftest rust-toggle-mutability-self ()
+  "Test toggling &self <-> &mut self."
+  (with-temp-buffer
+    (rust-mode)
+    (insert "    fn foo(&self) {")
+    (goto-char (line-end-position))
+    (rust-toggle-mutability)
+    (should (string-match-p "&mut self" (buffer-string)))
+    (goto-char (line-end-position))
+    (rust-toggle-mutability)
+    (should (string-match-p "&self" (buffer-string)))))
diff --git a/rust-utils.el b/rust-utils.el
index d93bd0a07f..b0b0ae17c1 100644
--- a/rust-utils.el
+++ b/rust-utils.el
@@ -108,15 +108,38 @@ if not. Move cursor to the end of macro."
    )
   )
 
+;;;###autoload
 (defun rust-toggle-mutability ()
-  "Toggles the mutability of the variable defined on the current line"
+  "Toggle the mutability of the binding or reference near point.
+Handles `let' <-> `let mut' and `&' <-> `&mut' (including `&self')."
   (interactive)
   (save-excursion
-    (back-to-indentation)
-    (forward-word)
-    (if (string= " mut" (buffer-substring (point) (+ (point) 4)))
-        (delete-region (point) (+ (point) 4))
-      (insert " mut"))))
+    (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

Reply via email to