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

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

[nongnu] elpa/swift-mode 0a75736 317/496: Fix indentation


From: ELPA Syncer
Subject: [nongnu] elpa/swift-mode 0a75736 317/496: Fix indentation
Date: Sun, 29 Aug 2021 11:33:58 -0400 (EDT)

branch: elpa/swift-mode
commit 0a75736666dc2ea548d976bdb05576d0d89f672f
Author: taku0 <mxxouy6x3m_github@tatapa.org>
Commit: taku0 <mxxouy6x3m_github@tatapa.org>

    Fix indentation
---
 swift-mode-indent.el                | 194 +++++++++++++++++++++++++-----------
 swift-mode-lexer.el                 |  45 +++++----
 test/swift-files/declarations.swift |   4 +-
 test/swift-files/statements.swift   |  31 ++++--
 test/swift-files/types.swift        |  10 +-
 5 files changed, 192 insertions(+), 92 deletions(-)

diff --git a/swift-mode-indent.el b/swift-mode-indent.el
index 87462cc..b1bca83 100644
--- a/swift-mode-indent.el
+++ b/swift-mode-indent.el
@@ -89,7 +89,7 @@
 
 (defconst swift-mode:expression-parent-tokens
   (append swift-mode:statement-parent-tokens
-          '(\, < "where" "if" "guard" "while"))
+          '(\, < supertype-: "where" "if" "guard" "while"))
   "Parent tokens for expressions.")
 
 (defun swift-mode:indent-line ()
@@ -158,23 +158,7 @@
      ((and next-is-on-same-line (memq next-type '(\) \])))
       (goto-char (swift-mode:token:end next-token))
       (backward-list)
-      (swift-mode:calculate-indent-of-expression
-       swift-mode:expression-parent-tokens
-       0
-       ;; Stops scanning at BOL:
-       ;;
-       ;; foo
-       ;;   .bar(
-       ;;     1
-       ;;   )
-       ;;
-       ;; rather than
-       ;;
-       ;; foo
-       ;;   .bar(
-       ;;   1
-       ;; )
-       'any))
+      (swift-mode:calculate-indent-of-expression 0))
 
      ;; Before , on the same line
      ((and next-is-on-same-line (eq next-type '\,))
@@ -223,7 +207,7 @@
       ;;       in
       ;;   a
       ;; }
-      (swift-mode:calculate-indent-of-expression '("for" {)))
+      (swift-mode:find-and-align-with-parents '("for" {)))
 
      ;; Before "case" or "default" on the same line, for switch statement
      ((and
@@ -282,7 +266,7 @@
                      '("switch") nil '("case" "default"))))
         (if (equal (swift-mode:token:text parent) "switch")
             ;; Inside a switch-statement. Aligns with the "switch"
-            (swift-mode:calculate-indent-of-expression
+            (swift-mode:find-and-align-with-parents
              swift-mode:statement-parent-tokens
              swift-mode:switch-case-offset)
           ;; Other cases. Aligns with the previous case.
@@ -327,7 +311,7 @@
       (let ((parent (save-excursion (swift-mode:backward-sexps-until
                                      (append swift-mode:statement-parent-tokens
                                              '("case"))))))
-        (swift-mode:calculate-indent-of-expression
+        (swift-mode:find-and-align-with-parents
          (append swift-mode:statement-parent-tokens
                  '(< "case" "catch" "for")
                  (if (equal (swift-mode:token:text parent) "case") '(\,) '()))
@@ -343,23 +327,7 @@
      ((memq previous-type '(\( \[))
       (goto-char (swift-mode:token:start previous-token))
       (swift-mode:calculate-indent-of-expression
-       swift-mode:expression-parent-tokens
        swift-mode:parenthesized-expression-offset
-       ;; Stops scanning at BOL:
-       ;;
-       ;; foo
-       ;;   .bar(
-       ;;     1
-       ;;   )
-       ;;
-       ;; rather than
-       ;;
-       ;; foo
-       ;;   .bar(
-       ;;   1
-       ;; )
-       'any
-       nil
        swift-mode:parenthesized-expression-offset))
 
      ;; After "where"
@@ -435,7 +403,7 @@
                         (swift-mode:backward-sexps-until
                          (append swift-mode:statement-parent-tokens
                                  '("case"))))))
-          (swift-mode:calculate-indent-of-expression
+          (swift-mode:find-and-align-with-parents
            (append swift-mode:statement-parent-tokens
                    '(< "case" "catch" "for")
                    (if (equal (swift-mode:token:text parent) "case") '(\,) 
'()))
@@ -444,7 +412,7 @@
      ;; After implicit-\; or ;
      ((memq previous-type '(implicit-\; \;))
       (goto-char (swift-mode:token:start previous-token))
-      (swift-mode:calculate-indent-of-expression
+      (swift-mode:find-and-align-with-parents
        (remove '\; (remove 'implicit-\; swift-mode:statement-parent-tokens))
        0
        '(implicit-\; \;)))
@@ -486,20 +454,20 @@
      ;; After case ... : or default:
      ((eq previous-type 'case-:)
       (goto-char (swift-mode:token:start previous-token))
-      (swift-mode:calculate-indent-of-expression
+      (swift-mode:find-and-align-with-parents
        swift-mode:statement-parent-tokens
        swift-mode:basic-offset))
 
      ;; Before ; on the same line
      ((and next-is-on-same-line (eq next-type '\;))
-      (swift-mode:calculate-indent-of-expression
+      (swift-mode:find-and-align-with-parents
        (remove '\; (remove 'implicit-\; swift-mode:statement-parent-tokens))
        0
        '(implicit-\; \;)))
 
      ;; After if, guard, while
      ((member previous-text '("if" "guard" "while"))
-      (swift-mode:calculate-indent-of-expression
+      (swift-mode:find-and-align-with-parents
        swift-mode:statement-parent-tokens
        swift-mode:multiline-statement-offset))
 
@@ -534,21 +502,19 @@
       (goto-char (swift-mode:token:end previous-token))
       (swift-mode:backward-token-or-list)
       (swift-mode:calculate-indent-of-expression
-       swift-mode:expression-parent-tokens
-       swift-mode:multiline-statement-offset
-       'any)))))
+       swift-mode:multiline-statement-offset)))))
 
-(defun swift-mode:calculate-indent-of-expression
+(defun swift-mode:find-and-align-with-parents
     (parents
      &optional
      offset
      stop-at-eol-token-types
      stop-at-bol-token-types
      bol-offset)
-  "Return start column of the current expressions or statement plus OFFSET.
+  "Return start column of the current expressions or statement plus offset.
 
-If OFFSET is omitted, it is assumed to be 0.
 PARENTS is a list of token types that precedes an expression or a statement.
+OFFSET is the offset.  If it is omitted, assumed to be 0.
 See `swift-mode:backward-sexps-until' for the details of
 STOP-AT-EOL-TOKEN-TYPES and STOP-AT-BOL-TOKEN-TYPES.
 If scanning stops at STOP-AT-EOL-TOKEN-TYPES, align with the next token with
@@ -590,6 +556,41 @@ on the previous line."
         ;; Aligns with this line with bol-offset.
         (swift-mode:align-with-current-line bol-offset)))))
 
+(defun swift-mode:calculate-indent-of-expression
+    (&optional
+     offset
+     bol-offset)
+  "Return start column of the current expressions plus offset.
+
+the cursor is assumed to be on the previous line.
+
+OFFSET is the offset.  If it is omitted, assumed to be 0.
+If scanning stops at eol, align with the next token with BOL-OFFSET."
+  (save-excursion
+    (let* ((pos (point))
+           (parent-of-previous-line
+            (progn (swift-mode:goto-non-comment-bol-with-same-nesting-level)
+                   (swift-mode:backward-token)))
+           (parent (progn (goto-char pos)
+                          (swift-mode:find-parent-of-expression))))
+      (if (<= (swift-mode:token:start parent-of-previous-line)
+              (swift-mode:token:start parent))
+          ;; let x =
+          ;;   1 + // here
+          ;;   2 +
+          ;;   3
+          ;;
+          ;; Aligns with the parent of the expression with offset.
+          (swift-mode:align-with-next-token parent offset)
+        ;; let x =
+        ;;   1 +
+        ;;   2 + // here
+        ;;   3   // or here
+        ;;
+        ;; Aligns with the previous line.
+        (swift-mode:align-with-next-token parent-of-previous-line
+                                          bol-offset)))))
+
 (defun swift-mode:calculate-indent-after-open-curly-brace (offset)
   "Return indentation after open curly braces.
 
@@ -733,12 +734,11 @@ This function is also used for close-curly-brace."
             (if (< (point) pos)
                 (setq next-token (swift-mode:forward-token-or-list))
               (goto-char (1+ pos))))))))
-    (swift-mode:calculate-indent-of-expression
-     swift-mode:statement-parent-tokens
-     offset
-     (if is-declaration-or-control-statement-body nil 'any)
-     nil
-     offset)))
+    (if is-declaration-or-control-statement-body
+        (swift-mode:find-and-align-with-parents
+         swift-mode:statement-parent-tokens
+         offset)
+      (swift-mode:calculate-indent-of-expression offset offset))))
 
 (defun swift-mode:calculate-indent-of-prefix-comma ()
   "Return indentation for prefix comma.
@@ -781,8 +781,8 @@ This is also known as Utrecht-style in the Haskell 
community."
 Assuming the cursor is on the comma."
   (swift-mode:align-with-next-token (swift-mode:find-parent-of-list-element 
nil)))
 
-(defun swift-mode:find-parent-of-list-element (utrecht-sytle)
-  "Move point backward to the parent token of comma under the cursor.
+(defun swift-mode:find-parent-of-list-element (&optional utrecht-sytle)
+  "Move point backward to the parent token of the comma under the cursor.
 If UTRECHT-SYTLE is non-nil, stop at a comma at bol.  Otherwise, stop at a
 comma at eol."
   ;; Various examples:
@@ -904,10 +904,10 @@ comma at eol."
                     '("guard" "while" "let" "var" "case" "where"))
             (setq result next-token))
 
-           ((eq (swift-mode:token:type next-token) 'typing-:)
+           ((eq (swift-mode:token:type next-token) 'supertype-:)
             (goto-char pos)
             (setq result (swift-mode:backward-sexps-until
-                          '(typing-: "where")))))
+                          '(supertype-: "where")))))
 
           (setq next-token (swift-mode:forward-token-or-list)))
         (when (and (> (point) pos)
@@ -915,12 +915,82 @@ comma at eol."
           ;; The comma was inside <> but scanner misunderstood < as
           ;; a binary-operator.
           (swift-mode:backward-token-or-list)
-          (setq result (swift-mode:backward-token)))
+          (setq result (swift-mode:forward-token)))
         (when (null result)
           (setq result parent))
         (goto-char (swift-mode:token:start result))
         result)))))
 
+(defun swift-mode:find-parent-of-expression ()
+  "Move point backward to the parent token of the expression under the cursor."
+  ;; TODO Unify with swift-mode:find-parent-of-list-element
+  (let ((pos (point))
+        (parent (swift-mode:backward-sexps-until
+                 swift-mode:expression-parent-tokens)))
+    (cond
+     ((memq (swift-mode:token:type parent) '(\( \[))
+      parent)
+
+     ((or
+       (memq (swift-mode:token:type parent)
+             swift-mode:statement-parent-tokens)
+       (member (swift-mode:token:text parent)
+               swift-mode:statement-parent-tokens)
+       (eq (swift-mode:token:type parent) 'outside-of-buffer))
+      (goto-char (swift-mode:token:end parent))
+      (let ((next-token (swift-mode:forward-token-or-list))
+            result)
+        (while (and (<= (point) pos) (not result))
+          (cond
+           ((member (swift-mode:token:text next-token)
+                    '("guard" "while" "case" "where"))
+            (setq result next-token))
+
+           ((member (swift-mode:token:text next-token)
+                    '("let" "var"))
+            ;; Special handling for "let" and "var".
+            ;;
+            ;; Declaring multiple variables with single let statement doesn't
+            ;; seem to be popular. Rather, we choose saving columns for the
+            ;; first variable:
+            ;;
+            ;; let x =
+            ;;   foo(),
+            ;;     y =
+            ;;       foo()
+            ;;
+            ;; rather than:
+            ;;
+            ;; let x =
+            ;;       foo(),
+            ;;     y =
+            ;;       foo()
+            ;;
+            ;; TODO make customizable
+            (setq result parent))
+
+           ((eq (swift-mode:token:type next-token) 'supertype-:)
+            parent))
+
+          (forward-comment (point-max))
+          (if (< (point) pos)
+              (setq next-token (swift-mode:forward-token-or-list))
+            (setq next-token (swift-mode:forward-token))))
+        (when (and (> (point) pos)
+                   (eq (swift-mode:token:type next-token) '<>))
+          ;; The expression was inside <> but scanner misunderstood < as
+          ;; a binary-operator.
+          (swift-mode:backward-token-or-list)
+          (setq result (swift-mode:forward-token)))
+        (when (null result)
+          (setq result parent))
+        (goto-char (swift-mode:token:start result))
+        result))
+
+     (t
+      parent))))
+
+
 (defun swift-mode:backward-sexps-until (token-types
                                         &optional
                                         stop-at-eol-token-types
@@ -1202,6 +1272,12 @@ Newlines inside comments are ignored."
       (forward-comment (- (point)))
       (<= (point) pos))))
 
+(defun swift-mode:goto-non-comment-bol-with-same-nesting-level ()
+  "Back to the beginning of line that is not inside a comment."
+  (while (not (swift-mode:bol-other-than-comments-p))
+    (swift-mode:backward-token-or-list)))
+
+
 (defun swift-mode:bolp ()
   "Return t if there is nothing in the front of this line.
 
diff --git a/swift-mode-lexer.el b/swift-mode-lexer.el
index 4465e9e..44a20dc 100644
--- a/swift-mode-lexer.el
+++ b/swift-mode-lexer.el
@@ -82,7 +82,7 @@
 ;; - implicit-;
 ;; - < (as an angle bracket)
 ;; - > (as an angle bracket)
-;; - typing-: (colon for supertype declaration or type declaration of let or 
var)
+;; - supertype-: (colon for supertype declaration or type declaration of let 
or var)
 ;; - case-: (colon for case or default label)
 ;; - : (part of conditional operator, key-value separator, label-statement 
separator)
 ;; - anonymous-function-parameter-in ("in" after anonymous function parameter)
@@ -391,38 +391,43 @@
     ;; Otherwise, inserts implicit semicolon.
     (t t))))
 
-(defun swift-mode:type-colon-p ()
-  "Return t if a colon at the cursor is the colon for type annotation.
+(defun swift-mode:supertype-colon-p ()
+  "Return t if a colon at the cursor is the colon for supertype.
 
 That is supertype declaration or type declaration of let or var."
   (save-excursion
     (let ((previous-token (swift-mode:backward-token-simple)))
-      ;; class Foo<T>: Bar ← type colon
-      ;; class Foo<T> : Bar ← type colon
-      ;; class Foo<T where T: Bar<[(Int, String)]>> : Bar ← type colon
-      ;; case Foo: ← not a type colon
-      ;; case Foo where foo: ← not a type colon
-      ;; default: ← not a type colon
-      ;; foo ? bar : baz ← not a type colon
+      ;; class Foo<T>: Bar ← supertype colon
+      ;; class Foo<T> : Bar ← supertype colon
+      ;; class Foo<T where T: Bar<[(Int, String)]>> : Bar ← supertype colon
+      ;; case Foo: ← not a supertype colon
+      ;; case Foo where foo: ← not a supertype colon
+      ;; case let Foo(x) where x is Foo<Int>: ← not a supertype colon
+      ;; default: ← not a supertype colon
+      ;; foo ? bar : baz ← not a supertype colon
       ;; [
-      ;;   foo: ← not a type colon
+      ;;   foo: ← not a supertype colon
       ;;     bar
       ;; ]
-      ;; foo(bar, baz: baz) ← not a type colon
+      ;; foo(bar, baz: baz) ← not a supertype colon
+      ;; protocol Foo {
+      ;;   associatedtype Bar<A>: Baz ← supertype colon
+      ;; }
       (or
+       ;; FIXME case let Foo(x) where x is Foo<Int>
        (eq (swift-mode:token:type previous-token) '>)
-       ;; class Foo: ← type colon
-       ;; extension Foo: ← type colon
-       ;; let foo: ← type colon
-       ;; var foo: ← type colon
+       ;; class Foo: ← supertype colon
+       ;; extension Foo: ← supertype colon
+       ;; let foo: ← not a supertype colon
+       ;; var foo: ← not a supertype colon
        ;; protocol Foo {
-       ;;   typealias Bar: Baz ← type colon
+       ;;   associatedtype Bar: Baz ← supertype colon
        ;; }
        (member (swift-mode:token:text
                 (swift-mode:backquote-identifier-if-after-dot
                  (swift-mode:backward-token-simple)))
                '("class" "extension" "enum" "struct" "protocol" "typealias"
-                 "associatedtype" "let" "var"))))))
+                 "associatedtype"))))))
 
 (defun swift-mode:case-colon-p ()
   "Return t if a colon at the cursor is the colon for case or default label."
@@ -545,7 +550,7 @@ type `out-of-buffer'"
      ;; Colon
      ((eq (char-after) ?:)
       (swift-mode:token (cond
-                         ((swift-mode:type-colon-p) 'typing-:)
+                         ((swift-mode:supertype-colon-p) 'supertype-:)
                          ((swift-mode:case-colon-p) 'case-:)
                          (t ':))
                         ":"
@@ -715,7 +720,7 @@ type `out-of-buffer'."
      ((eq (char-before) ?:)
       (backward-char)
       (swift-mode:token (cond
-                         ((swift-mode:type-colon-p) 'typing-:)
+                         ((swift-mode:supertype-colon-p) 'supertype-:)
                          ((swift-mode:case-colon-p) 'case-:)
                          (t ':))
                         ":"
diff --git a/test/swift-files/declarations.swift 
b/test/swift-files/declarations.swift
index 3a353de..e16fed6 100644
--- a/test/swift-files/declarations.swift
+++ b/test/swift-files/declarations.swift
@@ -292,13 +292,13 @@ fileprivate
     B =
       D<E> {
     case A =
-           1, // swift-mode:test:known-bug
+           1,
          B =
            2,
          C =
            3
     case D
-           = 1, // swift-mode:test:known-bug
+           = 1,
          E
            = 2,
          F
diff --git a/test/swift-files/statements.swift 
b/test/swift-files/statements.swift
index 67c6a28..3decd4f 100644
--- a/test/swift-files/statements.swift
+++ b/test/swift-files/statements.swift
@@ -365,6 +365,16 @@ if foo() {
     foo()
 }
 
+if foo.bar +++ {
+       foo()
+   },
+   foo.bar +++ {
+       foo()
+   } {
+    foo()
+}
+
+
 // Guard statement
 
 guard
@@ -566,7 +576,7 @@ default:
 
 switch foo {
 case let
-       .P(x) // swift-mode:test:known-bug
+       .P(x)
          where // swift-mode:test:known-bug
            foo
              .bar(),
@@ -590,7 +600,7 @@ default:
 switch foo {
 case
   let
-    .P(x) // swift-mode:test:known-bug
+    .P(x)
       where // swift-mode:test:known-bug
         foo
           .bar(),
@@ -614,7 +624,7 @@ default:
 switch foo {
 case
   let Foo
-    .P(x) // swift-mode:test:known-bug
+    .P(x)
       where // swift-mode:test:known-bug
         foo
           .bar(),
@@ -632,7 +642,7 @@ case
     foo()
 case
   Foo
-    .P, // swift-mode:test:known-bug
+    .P,
   Foo
     .Q,
   Foo
@@ -645,7 +655,7 @@ default:
 switch foo {
 case
   let
-    Foo // swift-mode:test:known-bug
+    Foo
     .P(x)
       where // swift-mode:test:known-bug
         foo
@@ -672,7 +682,7 @@ default:
 switch foo {
 case
   is
-    Foo // swift-mode:test:known-bug
+    Foo
       where // swift-mode:test:known-bug
         foo
           .bar(),
@@ -694,6 +704,15 @@ default:
     foo()
 }
 
+switch foo {
+case let .P(x) where x is Foo<Int>:
+    foo() // swift-mode:test:known-bug
+    foo() // swift-mode:test:known-bug
+default:
+    foo()
+    foo()
+}
+
 // swift-mode:test:eval (setq-local swift-mode:switch-case-offset 2)
 
 switch foo {
diff --git a/test/swift-files/types.swift b/test/swift-files/types.swift
index e058e44..cacf1e5 100644
--- a/test/swift-files/types.swift
+++ b/test/swift-files/types.swift
@@ -59,7 +59,7 @@ let foo
 
 class Foo:
   @A
-  A,
+  A, // swift-mode:test:known-bug
   B {
 }
 
@@ -94,7 +94,7 @@ let foo:
 
 class Foo:
   A.
-    B, // swift-mode:test:known-bug
+    B,
   A.
     B,
   A
@@ -103,7 +103,7 @@ class Foo:
 
 class Foo
   : A.
-      B, // swift-mode:test:known-bug
+      B,
     A.
       B,
     A
@@ -111,7 +111,7 @@ class Foo
 }
 
 class Foo: A.
-             B, // swift-mode:test:known-bug
+             B
          , A.
              B
          , A
@@ -121,7 +121,7 @@ class Foo: A.
 
 class Foo
   : A.
-      B // swift-mode:test:known-bug
+      B
   , A.
       B,
   , A



reply via email to

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