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

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

[nongnu] elpa/rust-mode eaf95af 210/486: Merge pull request #111 from mr


From: ELPA Syncer
Subject: [nongnu] elpa/rust-mode eaf95af 210/486: Merge pull request #111 from mrBliss/where-indentation
Date: Sat, 7 Aug 2021 09:25:20 -0400 (EDT)

branch: elpa/rust-mode
commit eaf95af109b2f90441fb4976678b1f058d2c4de8
Merge: 0601540 92584c3
Author: Felix S Klock II <pnkfelix@pnkfx.org>
Commit: Felix S Klock II <pnkfelix@pnkfx.org>

    Merge pull request #111 from mrBliss/where-indentation
    
    Correctly indent where clauses
---
 rust-mode-tests.el | 171 +++++++++++++++++++++++++++++++++++++++++++++++++++++
 rust-mode.el       |  80 +++++++++++++++++++++++--
 2 files changed, 247 insertions(+), 4 deletions(-)

diff --git a/rust-mode-tests.el b/rust-mode-tests.el
index e621f82..cc76007 100644
--- a/rust-mode-tests.el
+++ b/rust-mode-tests.el
@@ -443,6 +443,177 @@ fn foo4(a:int,
 }
 "))
 
+(ert-deftest indent-body-after-where ()
+  (test-indent
+   "
+fn foo1(a: A, b: B) -> A
+    where A: Clone + Default, B: Eq {
+    let body;
+    Foo {
+        bar: 3
+    }
+}
+
+fn foo2(a: A, b: B) -> A
+    where A: Clone + Default, B: Eq
+{
+    let body;
+    Foo {
+        bar: 3
+    }
+}
+"))
+
+(ert-deftest indent-align-where-clauses-style1a ()
+  (test-indent
+   "
+fn foo1a(a: A, b: B, c: C) -> D
+    where A: Clone + Default,
+          B: Eq,
+          C: PartialEq,
+          D: PartialEq {
+    let body;
+    Foo {
+        bar: 3
+    }
+}
+"))
+
+(ert-deftest indent-align-where-clauses-style1b ()
+  (test-indent
+   "
+fn foo1b(a: A, b: B, c: C) -> D
+    where A: Clone + Default,
+          B: Eq,
+          C: PartialEq,
+          D: PartialEq
+{
+    let body;
+    Foo {
+        bar: 3
+    }
+}
+"))
+
+(ert-deftest indent-align-where-clauses-style2a ()
+  (test-indent
+   "
+fn foo2a(a: A, b: B, c: C) -> D where A: Clone + Default,
+                                      B: Eq,
+                                      C: PartialEq,
+                                      D: PartialEq {
+    let body;
+    Foo {
+        bar: 3
+    }
+}
+"))
+
+(ert-deftest indent-align-where-clauses-style2b ()
+  (test-indent
+   "
+fn foo2b(a: A, b: B, c: C) -> D where A: Clone + Default,
+                                      B: Eq,
+                                      C: PartialEq,
+                                      D: PartialEq
+{
+    let body;
+    Foo {
+        bar: 3
+    }
+}
+"))
+
+(ert-deftest indent-align-where-clauses-style3a ()
+  (test-indent
+   "
+fn foo3a(a: A, b: B, c: C) -> D where
+    A: Clone + Default,
+    B: Eq,
+    C: PartialEq,
+    D: PartialEq {
+    let body;
+    Foo {
+        bar: 3
+    }
+}
+"))
+
+(ert-deftest indent-align-where-clauses-style3b ()
+  (test-indent
+   "
+fn foo3b(a: A, b: B, c: C) -> D where
+    A: Clone + Default,
+    B: Eq,
+    C: PartialEq,
+    D: PartialEq
+{
+    let body;
+    Foo {
+        bar: 3
+    }
+}
+"))
+
+(ert-deftest indent-align-where-clauses-style4a ()
+  (let ((rust-indent-where-clause nil))
+    (test-indent
+     "
+fn foo4a(a: A, b: B, c: C) -> D
+where A: Clone + Default,
+      B: Eq,
+      C: PartialEq,
+      D: PartialEq {
+    let body;
+    Foo {
+        bar: 3
+    }
+}
+")))
+
+(ert-deftest indent-align-where-clauses-style4b ()
+  (let ((rust-indent-where-clause nil))
+    (test-indent
+     "
+fn foo4b(a: A, b: B, c: C) -> D
+where A: Clone + Default,
+      B: Eq,
+      C: PartialEq,
+      D: PartialEq
+{
+    let body;
+    Foo {
+        bar: 3
+    }
+}
+")))
+
+(ert-deftest indent-align-where-clauses-impl-example ()
+  (test-indent
+   "
+impl<'a, K, Q: ?Sized, V, S> Index<&'a Q> for HashMap<K, V, S>
+    where K: Eq + Hash + Borrow<Q>,
+          Q: Eq + Hash,
+          S: HashState,
+{
+    let body;
+    Foo {
+        bar: 3
+    }
+}
+"))
+
+(ert-deftest indent-align-where-clauses-first-line ()
+  (test-indent
+   "fn foo1(a: A, b: B) -> A
+    where A: Clone + Default, B: Eq {
+    let body;
+    Foo {
+        bar: 3
+    }
+}
+"))
+
 (ert-deftest indent-square-bracket-alignment ()
   (test-indent
    "
diff --git a/rust-mode.el b/rust-mode.el
index 5b50d29..6b09580 100644
--- a/rust-mode.el
+++ b/rust-mode.el
@@ -157,6 +157,13 @@
   :group 'rust-mode
   :safe #'booleanp)
 
+(defcustom rust-indent-where-clause t
+  "Indent the line starting with the where keyword following a
+function or trait.  When nil, where will be aligned with fn or trait."
+  :type 'boolean
+  :group 'rust-mode
+  :safe #'booleanp)
+
 (defcustom rust-playpen-url-format "https://play.rust-lang.org/?code=%s";
   "Format string to use when submitting code to the playpen"
   :type 'string
@@ -213,7 +220,25 @@
       (back-to-indentation))
     (while (> (rust-paren-level) current-level)
       (backward-up-list)
-      (back-to-indentation))))
+      (back-to-indentation))
+    ;; When we're in the where clause, skip over it.  First find out the start
+    ;; of the function and its paren level.
+    (let ((function-start nil) (function-level nil))
+      (save-excursion
+        (rust-beginning-of-defun)
+        (back-to-indentation)
+        ;; Avoid using multiple-value-bind
+        (setq function-start (point)
+              function-level (rust-paren-level)))
+      ;; On a where clause
+      (when (or (looking-at "\\bwhere\\b")
+                ;; or in one of the following lines, e.g.
+                ;; where A: Eq
+                ;;       B: Hash <- on this line
+                (and (save-excursion
+                       (re-search-backward "\\bwhere\\b" function-start t))
+                     (= current-level function-level)))
+        (goto-char function-start)))))
 
 (defun rust-align-to-method-chain ()
   (save-excursion
@@ -348,6 +373,11 @@
               ((and (nth 4 (syntax-ppss)) (looking-at "*"))
                (+ 1 baseline))
 
+              ;; When the user chose not to indent the start of the where
+              ;; clause, put it on the baseline.
+              ((and (not rust-indent-where-clause) (looking-at "\\bwhere\\b"))
+               baseline)
+
               ;; If we're in any other token-tree / sexp, then:
               (t
                (or
@@ -361,6 +391,47 @@
                     ;; Point is now at the beginning of the containing set of 
braces
                     (rust-align-to-expr-after-brace)))
 
+                ;; When where-clauses are spread over multiple lines, clauses
+                ;; should be aligned on the type parameters.  In this case we
+                ;; take care of the second and following clauses (the ones
+                ;; that don't start with "where ")
+                (save-excursion
+                  ;; Find the start of the function, we'll use this to limit
+                  ;; our search for "where ".
+                  (let ((function-start nil) (function-level nil))
+                    (save-excursion
+                      (rust-beginning-of-defun)
+                      (back-to-indentation)
+                      ;; Avoid using multiple-value-bind
+                      (setq function-start (point)
+                            function-level (rust-paren-level)))
+                    ;; When we're not on a line starting with "where ", but
+                    ;; still on a where-clause line, go to "where "
+                    (when (and
+                           (not (looking-at "\\bwhere\\b"))
+                           ;; We're looking at something like "F: ..."
+                           (and (looking-at (concat rust-re-ident ":"))
+                                ;; There is a "where " somewhere after the
+                                ;; start of the function.
+                                (re-search-backward "\\bwhere\\b"
+                                                    function-start t)
+                                ;; Make sure we're not inside the function
+                                ;; already (e.g. initializing a struct) by
+                                ;; checking we are the same level.
+                                (= function-level level)))
+                      ;; skip over "where"
+                      (forward-char 5)
+                      ;; Unless "where" is at the end of the line
+                      (if (eolp)
+                          ;; in this case the type parameters bounds are just
+                          ;; indented once
+                          (+ baseline rust-indent-offset)
+                        ;; otherwise, skip over whitespace,
+                        (skip-chars-forward "[:space:]")
+                        ;; get the column of the type parameter and use that
+                        ;; as indentation offset
+                        (current-column)))))
+
                 (progn
                   (back-to-indentation)
                   ;; Point is now at the beginning of the current line
@@ -373,10 +444,11 @@
 
                        (save-excursion
                          (rust-rewind-irrelevant)
-                         ;; Point is now at the end of the previous ine
+                         ;; Point is now at the end of the previous line
                          (or
-                          ;; If we are at the first line, no indentation is 
needed, so stay at baseline...
-                          (= 1 (line-number-at-pos (point)))
+                          ;; If we are at the start of the buffer, no
+                          ;; indentation is needed, so stay at baseline...
+                          (= (point) 1)
                           ;; ..or if the previous line ends with any of these:
                           ;;     { ? : ( , ; [ }
                           ;; then we are at the beginning of an expression, so 
stay on the baseline...



reply via email to

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