emacs-elpa-diffs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[nongnu] elpa/rust-mode 5469d9b 297/486: fix rust indentation bug


From: ELPA Syncer
Subject: [nongnu] elpa/rust-mode 5469d9b 297/486: fix rust indentation bug
Date: Sat, 7 Aug 2021 09:25:39 -0400 (EDT)

branch: elpa/rust-mode
commit 5469d9bc3a13c75a8e98a86b6005d3540eb92524
Author: Tom Tromey <tom@tromey.com>
Commit: Tom Tromey <tom@tromey.com>

    fix rust indentation bug
    
    This patch fixes a bug I found where rust-mode would misindent code
    like:
    
    fn each_split_within<'a, F>(ss: &'a str, lim: usize, mut it: F)
                                -> bool where F: FnMut(&'a str) -> bool {
    }
    
    fn test_split_within() {
    }
    
    In particular the second "fn" would be indented a level.
    
    On the "fn" line, rust-mode-indent-line was calling
    rust-beginning-of-defun, which would go to the previous defun.  Fixing
    this required moving the definition of rust-top-item-beg-re higher in
    the file, before its first use (recent versions of Emacs insist on
    this).  And, this required removing the "^" from this regexp, which is
    ok because the sole use is already adding a "^".  Additionally, I moved
    the "\\_>" into the regexp, rather than have it added at the point of
    use, so that the new use would also benefit.
    
    This patch includes two new test cases.
---
 rust-mode-tests.el | 28 ++++++++++++++++++++++++++++
 rust-mode.el       | 25 +++++++++++++++++--------
 2 files changed, 45 insertions(+), 8 deletions(-)

diff --git a/rust-mode-tests.el b/rust-mode-tests.el
index 98230de..5abd4a7 100644
--- a/rust-mode-tests.el
+++ b/rust-mode-tests.el
@@ -1628,6 +1628,34 @@ fn main() {
 "
    )))
 
+(ert-deftest indent-function-after-where ()
+  (let ((rust-indent-method-chain t)) (test-indent
+   "
+fn each_split_within<'a, F>(ss: &'a str, lim: usize, mut it: F)
+                            -> bool where F: FnMut(&'a str) -> bool {
+}
+
+#[test]
+fn test_split_within() {
+}
+"
+   )))
+
+(ert-deftest indent-function-after-where-nested ()
+  (let ((rust-indent-method-chain t)) (test-indent
+   "
+fn outer() {
+    fn each_split_within<'a, F>(ss: &'a str, lim: usize, mut it: F)
+                                -> bool where F: FnMut(&'a str) -> bool {
+    }
+    #[test]
+    fn test_split_within() {
+    }
+    fn bar() {
+    }
+}
+"
+   )))
 
 (ert-deftest test-for-issue-36-syntax-corrupted-state ()
   "This is a test for a issue #36, which involved emacs's
diff --git a/rust-mode.el b/rust-mode.el
index 2307cc0..f1c3994 100644
--- a/rust-mode.el
+++ b/rust-mode.el
@@ -35,6 +35,14 @@
 (defconst rust-re-unsafe "unsafe")
 (defconst rust-re-extern "extern")
 
+;;; Start of a Rust item
+(defvar rust-top-item-beg-re
+  (concat "\\s-*\\(?:priv\\|pub\\)?\\s-*"
+          (regexp-opt
+           '("enum" "struct" "type" "mod" "use" "fn" "static" "impl"
+             "extern" "trait"))
+         "\\_>"))
+
 (defun rust-looking-back-str (str)
   "Like `looking-back' but for fixed strings rather than regexps (so that it's 
not so slow)"
   (let ((len (length str)))
@@ -394,6 +402,10 @@ buffer."
                   ;; our search for "where ".
                   (let ((function-start nil) (function-level nil))
                     (save-excursion
+                      ;; If we're already at the start of a function,
+                      ;; don't go back any farther.  We can easily do
+                      ;; this by moving to the end of the line first.
+                      (end-of-line)
                       (rust-beginning-of-defun)
                       (back-to-indentation)
                       ;; Avoid using multiple-value-bind
@@ -437,6 +449,10 @@ buffer."
                        ;; baseline as well.
                        (looking-at "\\<else\\>\\|{\\|/[/*]")
 
+                       ;; If this is the start of a top-level item,
+                       ;; stay on the baseline.
+                       (looking-at rust-top-item-beg-re)
+
                        (save-excursion
                          (rust-rewind-irrelevant)
                          ;; Point is now at the end of the previous line
@@ -1136,13 +1152,6 @@ Use idomenu (imenu with `ido-mode') for best mileage.")
 
 ;;; Defun Motions
 
-;;; Start of a Rust item
-(defvar rust-top-item-beg-re
-  (concat "^\\s-*\\(?:priv\\|pub\\)?\\s-*"
-          (regexp-opt
-           '("enum" "struct" "type" "mod" "use" "fn" "static" "impl"
-             "extern" "trait"))))
-
 (defun rust-beginning-of-defun (&optional arg)
   "Move backward to the beginning of the current defun.
 
@@ -1153,7 +1162,7 @@ This is written mainly to be used as 
`beginning-of-defun-function' for Rust.
 Don't move to the beginning of the line. `beginning-of-defun',
 which calls this, does that afterwards."
   (interactive "p")
-  (re-search-backward (concat "^\\(" rust-top-item-beg-re "\\)\\_>")
+  (re-search-backward (concat "^\\(" rust-top-item-beg-re "\\)")
                       nil 'move (or arg 1)))
 
 (defun rust-end-of-defun ()



reply via email to

[Prev in Thread] Current Thread [Next in Thread]