branch: elpa/swift-mode commit 195d040921791722f4effb9690c721158421f6d7 Merge: 3026464 95e753b Author: Bozhidar Batsov <bozhidar.bat...@gmail.com> Commit: Bozhidar Batsov <bozhidar.bat...@gmail.com>
Merge pull request #76 from ap4y/batch_smie_fixes Batch smie fixes --- .travis.yml | 1 - swift-mode.el | 204 ++++++--- test/indentation-tests.el | 1113 ++++++++++++++++++++++++++++++++++++++++++++- 3 files changed, 1247 insertions(+), 71 deletions(-) diff --git a/.travis.yml b/.travis.yml index a066c7c..257daab 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,7 +1,6 @@ language: emacs-lisp env: - - EVM_EMACS=emacs-24.3-bin - EVM_EMACS=emacs-24.4-bin before_install: diff --git a/swift-mode.el b/swift-mode.el index 7646ecd..bceab2a 100644 --- a/swift-mode.el +++ b/swift-mode.el @@ -6,7 +6,7 @@ ;; Bozhidar Batsov <bozhi...@batsov.com> ;; Arthur Evstifeev <l...@pisem.net> ;; Version: 0.4.0-cvs -;; Package-Requires: ((emacs "24.1")) +;; Package-Requires: ((emacs "24.4")) ;; Keywords: languages swift ;; This file is not part of GNU Emacs. @@ -56,7 +56,7 @@ :type 'integer) (defcustom swift-indent-multiline-statement-offset 2 - "Defines the indentation offset for for multiline statements." + "Defines the indentation offset for multiline statements." :group 'swift :type 'integer :package-version '(swift-mode "0.3.0")) @@ -75,7 +75,7 @@ (smie-merge-prec2s (smie-bnf->prec2 '((id) - (type (type) (type "<T" types "T>")) + (type (type) (type "<T" types "T>") ("[" type "]")) (types (type) (type "," type)) (class-decl-exp (id) (id ":" types)) @@ -99,24 +99,36 @@ (top-level-st ("import" type) (decl) - ("class" class-decl-exp "{" class-level-sts "}")) + ("ACCESSMOD" "class" class-decl-exp "{" class-level-sts "}") + ("ACCESSMOD" "protocol" class-decl-exp "{" protocol-level-sts "}")) (class-level-sts (class-level-st) (class-level-st ";" class-level-st)) (class-level-st (decl) - ("DECSPEC" "func" func-header "{" insts "}")) + (func)) + (protocol-level-sts (protocol-level-st) (protocol-level-st ";" protocol-level-st)) + (protocol-level-st + (decl) + (func-decl)) + + (func-body (insts) ("return" exp)) + (func (func-decl "{" func-body "}")) + (func-decl ("DECSPEC" "func" func-header) + (func-decl "->" type)) (func-header (id "(" func-params ")")) - (func-param (decl-exp) ("...")) + (func-param (decl-exp) (decl-exp "=" id) ("...")) (func-params (func-param "," func-param)) (insts (inst) (insts ";" insts)) (inst (decl) + (exp "=" exp) + (tern-exp) (in-exp) (dot-exp) - (dot-exp "{" insts "}") + (dot-exp "{" closure "}") (method-call) - (method-call "{" insts "}") + (method-call "{" closure "}") ("enum" decl-exp "{" enum-body "}") ("switch" exp "{" switch-body "}") (if-clause) @@ -127,33 +139,36 @@ (method-call (dot-exp "(" method-args ")")) (method-args (method-arg) (method-arg "," method-arg)) - (method-arg (exp "," "{" insts "}") (exp)) + (method-arg (exp "," "{" closure "}") (exp)) (exp (op-exp) ("[" decl-exps "]")) (in-exp (id "in" exp)) (guard-exp (exp "where" exp)) (op-exp (exp "OP" exp)) + (tern-exp (op-exp "?" exp ":" exp)) - (enum-cases (assign-exp) - (enum-cases ";" "ecase" enum-cases)) + (enum-case ("ecase" assign-exp) + ("ecase" "(" type ")")) + (enum-cases (enum-case) (enum-case ";" enum-case)) (enum-body (enum-cases) (insts)) - (case-exps (guard-exp)) - (cases (case-exps ":" insts) - (cases "case" cases)) - (switch-body (cases) (cases "default:" insts)) + (case-exps (exp) (guard-exp)) + (case (case-exps ":" insts)) + (switch-body (case) (case "case" case)) (for-head (in-exp) (op-exp) (for-head ";" for-head)) - (conditional (exp) (let-decl)) - (if-body ("if" conditional "{" insts "}")) - (if-else-if (if-body) (if-else-if "else" if-else-if)) - (if-clause (if-else-if))) + (if-conditional (exp) (let-decl)) + (if-body ("if" if-conditional "{" insts "}")) + (if-clause (if-body) + (if-body "elseif" if-conditional "{" insts "}") + (if-body "else" "{" insts "}")) + + (closure (insts) (exp "in" insts) (exp "->" id "in" insts))) ;; Conflicts - '((nonassoc "{") (assoc ",") (assoc ";") (assoc ":")) + '((nonassoc "{") (assoc "in") (assoc ",") (assoc ";") (assoc ":") (right "=")) '((assoc "in") (assoc "where") (assoc "OP")) - '((assoc "else")) '((assoc ";") (assoc "ecase")) '((assoc "case"))) @@ -187,22 +202,39 @@ "is" "as" "as?" ".." "..." "+" "-" "&+" "&-" "|" "^" "*" "/" "%" "&*" "&/" "&%" "&" - "<<" ">>"))) + "<<" ">>" "??"))) (defvar swift-smie--decl-specifier-regexp - (rx (? (or "class" "mutating" "override" "static" "unowned" "weak")) - (* space) "func")) + "\\(?1:class\\|mutating\\|override\\|static\\|unowned\\|weak\\)\\(?:[[:space:]]*func\\)") + +(defvar swift-smie--access-modifier-regexp + (regexp-opt '("private" "public" "internal"))) (defun swift-smie--implicit-semi-p () (save-excursion - (not (or (memq (char-before) '(?\{ ?\[ ?, ?.)) - (looking-at "[ \n\t]+[.]") - (looking-back swift-smie--operators-regexp (- (point) 3) t) + (not (or (memq (char-before) '(?\{ ?\[ ?, ?. ?: ?= ?\()) + ;; Checking for operators form for "?" and "!", + ;; they can be a part of the type. + ;; Special case: is? and as? are operators. + (looking-back "[[:space:]][?!]" (- (point) 2) t) + ;; ??, is? and as? are operators + (looking-back "[?][?]\\|as[?]\\|is[?]" (- (point) 3) t) + ;; "in" operator in closure + (looking-back "in" (- (point) 2) t) + ;; Characters placed on the second line in multi-line expression + (looking-at "[ \n\t]+[.?:]") + ;; Operators placed on the second line in multi-line expression + ;; Should respect here possible comments strict before the linebreak + (looking-at (concat "\\(\/\/.*\\)?\n[[:space:]]*" swift-smie--operators-regexp)) + (and (looking-back swift-smie--operators-regexp (- (point) 3) t) + ;; Not a generic type + (not (looking-back "[[:upper:]]>" (- (point) 2) t))) )))) (defun swift-smie--forward-token () + (skip-chars-forward " \t") (cond - ((and (looking-at "\n") (swift-smie--implicit-semi-p)) + ((and (looking-at "\n\\|\/\/") (swift-smie--implicit-semi-p)) (if (eolp) (forward-char 1) (forward-comment 1)) ";") @@ -210,6 +242,9 @@ ((looking-at "}") (forward-char 1) "}") ((looking-at ",") (forward-char 1) ",") + ((looking-at ":") (forward-char 1) ":") + + ((looking-at "->") (forward-char 2) "->") ((looking-at "<") (forward-char 1) (if (looking-at "[[:upper:]]") "<T" "OP")) @@ -220,12 +255,21 @@ (goto-char (match-end 0)) "OP") ((looking-at swift-smie--decl-specifier-regexp) - (goto-char (match-end 0)) "DECSPEC") + (goto-char (match-end 1)) "DECSPEC") + + ((looking-at swift-smie--access-modifier-regexp) + (goto-char (match-end 0)) "ACCESSMOD") + + ((looking-at "\\<default\\>") + (goto-char (match-end 0)) "case") + + ((looking-at "else if") + (goto-char (match-end 0)) "elseif") (t (let ((tok (smie-default-forward-token))) (cond ((equal tok "case") - (if (looking-at ".+\\(,\\|:\\)") + (if (looking-at "\\([\n\t ]\\|.\\)+?\\(where.*[,]\\|:\\)") "case" "ecase")) (t tok)))) @@ -243,22 +287,36 @@ ((eq (char-before) ?\}) (backward-char 1) "}") ((eq (char-before) ?,) (backward-char 1) ",") + ((eq (char-before) ?:) (backward-char 1) ":") + + ((looking-back "->" (- (point) 2) t) + (goto-char (match-beginning 0)) "->") ((eq (char-before) ?<) (backward-char 1) (if (looking-at "<[[:upper:]]") "<T" "OP")) - ((eq (char-before) ?>) (backward-char 1) + ((looking-back ">[?!]?" (- (point) 2) t) + (goto-char (match-beginning 0)) (if (looking-back "[[:space:]]" 1 t) "OP" "T>")) ((looking-back swift-smie--operators-regexp (- (point) 3) t) (goto-char (match-beginning 0)) "OP") ((looking-back swift-smie--decl-specifier-regexp (- (point) 8) t) - (goto-char (match-beginning 0)) "DECSPEC") + (goto-char (match-beginning 1)) "DECSPEC") + + ((looking-back swift-smie--access-modifier-regexp (- (point) 8) t) + (goto-char (match-beginning 0)) "ACCESSMOD") + + ((looking-back "\\<default\\>" (- (point) 9) t) + (goto-char (match-beginning 0)) "case") + + ((looking-back "else if" (- (point) 7) t) + (goto-char (match-beginning 0)) "elseif") (t (let ((tok (smie-default-backward-token))) (cond ((equal tok "case") - (if (looking-at ".+\\(,\\|:\\)") + (if (looking-at "\\([\n\t ]\\|.\\)+?\\(where.*[,]\\|:\\)") "case" "ecase")) (t tok)))) @@ -268,43 +326,73 @@ (pcase (cons kind token) (`(:elem . basic) swift-indent-offset) + (`(:after . ":") 0) + (`(:before . ":") + (cond + ;; Rule for ternary operator in + ;; assignment expression. + ;; Static indentation relatively to = + ((smie-rule-parent-p "=") 2) + ;; Rule for the case statement. + ((smie-rule-parent-p "case") swift-indent-offset) + ;; Rule for the class definition. + ((smie-rule-parent-p "class") (smie-rule-parent swift-indent-offset)))) + (`(:after . "{") (if (smie-rule-parent-p "switch") (smie-rule-parent swift-indent-switch-case-offset))) (`(:before . ";") - (if (smie-rule-parent-p "case" "default:") + (if (smie-rule-parent-p "case") (smie-rule-parent swift-indent-offset))) ;; Apply swift-indent-multiline-statement-offset only if - ;; - dot is followed by newline, or - ;; - if dot is a first token on the line + ;; - if is a first token on the line (`(:before . ".") - (if (or (looking-at "[.][\n]") - (smie-rule-bolp)) - swift-indent-multiline-statement-offset)) + (when (smie-rule-bolp) + (if (smie-rule-parent-p "{") + (+ swift-indent-offset swift-indent-multiline-statement-offset) + swift-indent-multiline-statement-offset))) ;; Apply swift-indent-multiline-statement-offset if ;; operator is the last symbol on the line (`(:before . "OP") - (if (and (looking-at ".[\n]") - (not (smie-rule-sibling-p))) - swift-indent-multiline-statement-offset)) + (when (and (smie-rule-hanging-p) + (not (smie-rule-parent-p "OP"))) + (if (smie-rule-parent-p "{") + (+ swift-indent-offset swift-indent-multiline-statement-offset) + swift-indent-multiline-statement-offset))) ;; Indent second line of the multi-line class ;; definitions with swift-indent-offset (`(:before . ",") (if (smie-rule-parent-p "class") - swift-indent-offset)) + (smie-rule-parent swift-indent-offset))) - (`(:before . "if") - (if (smie-rule-prev-p "else") - (if (smie-rule-parent-p "{") - swift-indent-offset - (smie-rule-parent)))) + ;; Disable unnecessary default indentation for + ;; "func" and "class" keywords + (`(:after . ,(or `"func" `"class")) (smie-rule-parent)) + ;; "in" token in closure + (`(:after . "in") + (if (smie-rule-parent-p "{") + (smie-rule-parent swift-indent-offset))) + + (`(:after . "(") + (if (smie-rule-parent-p "(") 0 + (smie-rule-parent swift-indent-offset))) (`(:before . "(") - (if (smie-rule-next-p "[") (smie-rule-parent))) - (`(:before . "[") (smie-rule-parent)) + (cond + ((smie-rule-next-p "[") (smie-rule-parent)) + ;; Custom indentation for method arguments + ((smie-rule-parent-p "." "func") (smie-rule-parent)))) + + (`(:before . "[") + (cond + ((smie-rule-prev-p "->") swift-indent-offset) + ((smie-rule-parent-p "[") (smie-rule-parent swift-indent-offset)) + ((smie-rule-parent-p "{") nil) + (t (smie-rule-parent)))) + (`(:after . "->") (smie-rule-parent swift-indent-offset)) )) ;;; Font lock @@ -602,11 +690,23 @@ You can send text to the REPL process from other buffers containing source. ;; Parenthesis, braces and brackets (modify-syntax-entry ?\( "()" table) (modify-syntax-entry ?\) ")(" table) - (modify-syntax-entry ?\{ "(}" table) - (modify-syntax-entry ?\} "){" table) (modify-syntax-entry ?\[ "(]" table) (modify-syntax-entry ?\] ")[" table) + ;; HACK: This is not a correct syntax table definition + ;; for the braces, but it allows us disable smie indentation + ;; based on syntax-table. Default behaviour doesn't work with + ;; closures in method arguments. For example: + ;; + ;; foo.bar(10, + ;; closure: { + ;; }) + ;; + ;; With enabled syntax table, smie doesn't respect closing brace, so + ;; it's impossible to provide custom indentation rules + (modify-syntax-entry ?\{ "w" table) + (modify-syntax-entry ?\} "w" table) + table)) (defvar swift-mode-map diff --git a/test/indentation-tests.el b/test/indentation-tests.el index cb810b1..8be3235 100644 --- a/test/indentation-tests.el +++ b/test/indentation-tests.el @@ -264,6 +264,35 @@ switch true { } ") +(check-indentation indents-case-statements-to-same-level-as-enclosing-switch/5 + " +switch { + |case foo, + bar, buz: + foo +} +" " +switch { +|case foo, + bar, buz: + foo +} +") + +(check-indentation indents-case-statements-to-same-level-as-enclosing-switch/6 + " +switch { + |case + foo, bar, buz: + foo +} +" " +switch { +|case + foo, bar, buz: + foo +} +") (check-indentation indents-case-statement-bodies/1 " @@ -388,15 +417,36 @@ case y: } ") +(check-indentation indents-statements-under-default-case/1 + " +{ + switch true { + case y: + x + default: + |z + } +} +" " +{ + switch true { + case y: + x + default: + |z + } +} +") + (check-indentation indents-case-statements-with-destucturing/1 " switch true { -case let(x, y): +case let(x, y) where x < y: |foo } " " switch true { -case let(x, y): +case let(x, y) where x < y: |foo } ") @@ -404,12 +454,12 @@ case let(x, y): (check-indentation indents-case-statements-with-destucturing/2 " switch true { -case let .Foo(x): +case let .Foo(x) where x > 0: |foo } " " switch true { -case let .Foo(x): +case let .Foo(x) where x > 0: |foo } ") @@ -639,6 +689,57 @@ class Foo: Foo, Bar, } ") +(check-indentation indents-class-declaration/6 + " +class Foo: +|Foo, Bar, Baz { +} +" " +class Foo: + |Foo, Bar, Baz { +} +") + +(check-indentation indents-class-declaration/7 + " +class Foo: Bar<A, B, +|C> +" " +class Foo: Bar<A, B, + |C> +") + +(check-indentation indents-class-declaration/9 + " +class Foo<A: B<C>>: + |Bar +" " +class Foo<A: B<C>>: + |Bar +") + +(check-indentation indents-public-class-declaration/1 + " +public class Foo: Foo, Bar, +|Baz { +} +" " +public class Foo: Foo, Bar, + |Baz { +} +") + +(check-indentation indents-public-class-declaration/2 + " +public class Foo { + |foo +} +" " +public class Foo { + |foo +} +") + (check-indentation indents-func-declaration/1 " func Foo(a: String) { @@ -687,7 +788,7 @@ class Foo { } ") -(check-indentation indents-func-declaration/2 +(check-indentation indents-func-declaration/5 " class func Foo() { |foo @@ -698,6 +799,135 @@ class func Foo() { } ") +(check-indentation indents-func-declaration/6 + " +func Foo(aaaaaaaaa: + |AAAAAAAAA) { +} +" " +func Foo(aaaaaaaaa: + |AAAAAAAAA) { +} +") + +(check-indentation indents-func-declaration/7 + " +func foo() -> +|Foo +" " +func foo() -> + |Foo +") + +(check-indentation indents-func-declaration/8 + " +func foo() -> +|(A, B) {} +" " +func foo() -> + |(A, B) {} +") + +(check-indentation indents-func-declaration/9 + " +func foo() -> +|[A] {} +" " +func foo() -> + |[A] {} +") + +(check-indentation indents-func-declaration/10 + " +func a(a: NSString = 1, + |b: NSString = 2) {} +" " +func a(a: NSString = 1, + |b: NSString = 2) {} +") + +(check-indentation indents-func-declaration/11 + " +class Foo: Bar { + func Foo() { +|foo + } +} +" " +class Foo: Bar { + func Foo() { + |foo + } +} +") + +(check-indentation indents-func-declaration/12 + " +class Foo: Bar { + override func Foo() { +|foo + } +} +" " +class Foo: Bar { + override func Foo() { + |foo + } +} +") + +(check-indentation indents-protocol-declaration/1 + " +protocol Foo { + func foo() +|func bar() +} +" " +protocol Foo { + func foo() + |func bar() +} +") + +(check-indentation indents-protocol-declaration/2 + " +protocol Foo { + func foo() -> Foo +|func bar() -> Bar +} +" " +protocol Foo { + func foo() -> Foo + |func bar() -> Bar +} +") + +(check-indentation indents-protocol-declaration/3 + " +protocol Foo { + func foo() -> Foo<A> +|func bar() -> Bar<A> +} +" " +protocol Foo { + func foo() -> Foo<A> + |func bar() -> Bar<A> +} +") + +(check-indentation indents-protocol-declaration/4 + " +protocol Foo { + func foo() -> [A] +|func bar() -> [A] +} +" " +protocol Foo { + func foo() -> [A] + |func bar() -> [A] +} +") + (check-indentation indents-declaration/1 " var foo = bar + baz @@ -764,6 +994,131 @@ var result = Dictionary<String, V>() var result = Dictionary<String, V>() |foo ") +(check-indentation indents-declaration/8 + " +let foo = +|bar +" " +let foo = + |bar +") + +(check-indentation indents-declaration/9 + " +let foo: Foo? = +|bar +" " +let foo: Foo? = + |bar +") + +(check-indentation indents-declaration/10 + " +let foo: Foo<A> = +|bar +" " +let foo: Foo<A> = + |bar +") + +(check-indentation indents-declaration/11 + " +let foo = [ + foo: +|bar +] +" " +let foo = [ + foo: + |bar +] +") + +(check-indentation indents-declaration/12 + " +let foo = [ +|[ +" " +let foo = [ + |[ +") + +(check-indentation indents-declaration/13 + " +let foo = [ +|[ + bar: baz + ] +] +" " +let foo = [ + |[ + bar: baz + ] +] +") + +(check-indentation indents-declaration/14 + " +let foo = [ + [ + |bar: baz + ] +] +" " +let foo = [ + [ + |bar: baz + ] +] +") + +(check-indentation indents-declaration/15 + " +let foo = [ + [ + bar: baz +|] +] +" " +let foo = [ + [ + bar: baz + |] +] +") + +(check-indentation indents-expressions/1 + " +class Foo { + func a() { + |[a] + } +} +" " +class Foo { + func a() { + |[a] + } +} +") + +(check-indentation indents-expressions/2 + " +class Foo { + func a() { + a + |[a] + } +} +" " +class Foo { + func a() { + a + |[a] + } +} +") (check-indentation indents-multiline-expressions/1 " @@ -839,17 +1194,245 @@ let options = NSRegularExpressionOptions.CaseInsensitive & |NSRegularExpressionOptions.DotMatchesLineSeparators ") -(check-indentation indents-multiline-expressions-to-user-defined-offset/1 +(check-indentation indents-multiline-expressions/9 " -NSNotificationCenter.defaultCenter(). -|postNotificationName(foo, object: nil) +foo?[bar] + + |a " " -NSNotificationCenter.defaultCenter(). - |postNotificationName(foo, object: nil) -" -((swift-indent-multiline-statement-offset 4))) +foo?[bar] + + |a +") -(check-indentation indents-multiline-expressions-to-user-defined-offset/2 +(check-indentation indents-multiline-expressions/10 + " +foo?(bar) + + |a +" " +foo?(bar) + + |a +") + +(check-indentation indents-multiline-expressions/11 + " +func a () { + a + +|a +" " +func a () { + a + + |a +") + +(check-indentation indents-multiline-expressions/12 + " +func a () { + a +|.a() +" " +func a () { + a + |.a() +") + +(check-indentation indents-multiline-expressions/13 + " +if (a +|.b) +" " +if (a + |.b) +") + +(check-indentation indents-multiline-expressions/14 + " +a ?? +|b +" " +a ?? + |b +") + +(check-indentation indents-multiline-expressions/15 + " +a as +|b +" " +a as + |b +") + +(check-indentation indents-multiline-expressions/16 + " +a as? +|b +" " +a as? + |b +") + +(check-indentation indents-multiline-expressions/17 + " +a is +|b +" " +a is + |b +") + +(check-indentation indents-multiline-expressions/18 + " +CGPoint(x: aaaaaaaaaaaaaaa.x + +|bbbbbbbbbbbbbbbb, + y: aaaaaaaaaaaaaaa.y + + bbbbbbbbbbbbbbbb) +" " +CGPoint(x: aaaaaaaaaaaaaaa.x + + |bbbbbbbbbbbbbbbb, + y: aaaaaaaaaaaaaaa.y + + bbbbbbbbbbbbbbbb) +") + +(check-indentation indents-multiline-expressions/19 + " +let x = 1 +|+ 1 +" " +let x = 1 + |+ 1 +") + +(check-indentation indents-multiline-expressions/20 + " +let x = foo ?? + |bar +" " +let x = foo ?? + |bar +") + +(check-indentation indents-multiline-expressions/21 + " +let foo = a + + b + + |c + + d +" " +let foo = a + + b + + |c + + d +") + +(check-indentation indents-multiline-expressions/22 + " +let foo = a + + b + + c + + |d +" " +let foo = a + + b + + c + + |d +") + +(check-indentation indents-multiline-expressions/23 + " +let x = bar + .buz() ?? +|defaultValue +" " +let x = bar + .buz() ?? + |defaultValue +") + +(check-indentation indents-long-parameters/1 + " +func foo() { + timer = NSTimer.scheduledTimerWithTimeInterval( + |1.0, + target: self, + selector: Selector(\"onTimer\"), + userInfo: nil, + repeats: true) +} +" " +func foo() { + timer = NSTimer.scheduledTimerWithTimeInterval( + |1.0, + target: self, + selector: Selector(\"onTimer\"), + userInfo: nil, + repeats: true) +} +") + +(check-indentation indents-long-parameters/2 + " +aaaaaa.aaaaaaaaaaaaaaaaaaaaa( + |aaaaaaaaaaaaaaaaaaaaa +) +" " +aaaaaa.aaaaaaaaaaaaaaaaaaaaa( + |aaaaaaaaaaaaaaaaaaaaa +) +") + +(check-indentation indents-long-parameters/3 + " +public func tableView( +|tableView: UITableView, + commitEditingStyle editingStyle: UITableViewCellEditingStyle, + forRowAtIndexPath indexPath: NSIndexPath) { +} +" " +public func tableView( + |tableView: UITableView, + commitEditingStyle editingStyle: UITableViewCellEditingStyle, + forRowAtIndexPath indexPath: NSIndexPath) { +} +") + +(check-indentation indents-long-parameters/4 + " +func a( + |a: a, + a: a, + a: a) { +} +" " +func a( + |a: a, + a: a, + a: a) { +} +") + +(check-indentation indents-long-parameters/5 + " +func foo() { + timer = NSTimer.scheduledTimerWithTimeInterval( + 1.0, + target: self, + selector: Selector(\"onTimer\"), + userInfo: nil, + repeats: true +|) +} +" " +func foo() { + timer = NSTimer.scheduledTimerWithTimeInterval( + 1.0, + target: self, + selector: Selector(\"onTimer\"), + userInfo: nil, + repeats: true + |) +} +") + +(check-indentation indents-multiline-expressions-to-user-defined-offset/1 " NSNotificationCenter.defaultCenter() |.postNotificationName(foo, object: nil) @@ -859,7 +1442,7 @@ NSNotificationCenter.defaultCenter() " ((swift-indent-multiline-statement-offset 4))) -(check-indentation indents-multiline-expressions-to-user-defined-offset/3 +(check-indentation indents-multiline-expressions-to-user-defined-offset/2 " let json_ary = NSJSONSerialization |.JSONObjectWithData(data, options: nil, error: &json_err) as NSArray @@ -869,7 +1452,7 @@ let json_ary = NSJSONSerialization " ((swift-indent-multiline-statement-offset 4))) -(check-indentation indents-multiline-expressions-to-user-defined-offset/4 +(check-indentation indents-multiline-expressions-to-user-defined-offset/3 " let options = NSRegularExpressionOptions.CaseInsensitive & |NSRegularExpressionOptions.DotMatchesLineSeparators @@ -922,15 +1505,509 @@ let foo = bar > (check-indentation indents-multiline-operators-only-once " 1 + - 2 + 5 * + 2 + 5 * |3 " " 1 + - 2 + 5 * - |3 + 2 + 5 * + |3 " ) +(check-indentation conditional-operator/1 + " +let a = a + |? a + + 1 + : a + + 1 +" " +let a = a + |? a + + 1 + : a + + 1 +") + +(check-indentation conditional-operator/2 + " +let a = a + ? a + + |1 + : a + + 1 +" " +let a = a + ? a + + |1 + : a + + 1 +") + +(check-indentation conditional-operator/3 + " +let a = a + ? a + + 1 + |: a + + 1 +" " +let a = a + ? a + + 1 + |: a + + 1 +") + +(check-indentation conditional-operator/4 + " +let a = a + ? a + + 1 + : a + + |1 +" " +let a = a + ? a + + 1 + : a + + |1 +") + +(check-indentation conditional-operator/5 + " +let a = a ? +|a : a +" " +let a = a ? + |a : a +") + +(check-indentation conditional-operator/6 + " +let a = a ? + |b : + c +" " +let a = a ? + |b : + c +") + +(check-indentation conditional-operator/7 + " +let a = a ? + b : + |c +" " +let a = a ? + b : + |c +") + +(check-indentation conditional-operator/8 + " +func foo() { + return order!.deliver ? + |OrderViewTableDeliveryCells.lastCellIndex.rawValue : + OrderViewTableTakeAwayCells.lastCellIndex.rawValue +} +" " +func foo() { + return order!.deliver ? + |OrderViewTableDeliveryCells.lastCellIndex.rawValue : + OrderViewTableTakeAwayCells.lastCellIndex.rawValue +} +") + +(check-indentation conditional-operator/9 + " +func foo() { + return order!.deliver ? + OrderViewTableDeliveryCells.lastCellIndex.rawValue : + |OrderViewTableTakeAwayCells.lastCellIndex.rawValue +} +" " +func foo() { + return order!.deliver ? + OrderViewTableDeliveryCells.lastCellIndex.rawValue : + |OrderViewTableTakeAwayCells.lastCellIndex.rawValue +} +") + +(check-indentation blank-line/1 + " +func foo() { + let a = 1 + +|let b = 1 +} +" " +func foo() { + let a = 1 + + |let b = 1 +} +") + +(check-indentation block-inside-parenthesis/3 + " +\({ +|a +}) +" " +\({ + |a +}) +") + +(check-indentation indent-long-if-else-if/1 + " +if a { + a +} else if a { + a +} else if a { + |a +} else { + a +} +" " +if a { + a +} else if a { + a +} else if a { + |a +} else { + a +} +") + +(check-indentation indent-long-if-else-if/2 + " +if a { + a +} else if a { + a +} else if a { + a +|} else { + a +} +" " +if a { + a +} else if a { + a +} else if a { + a +|} else { + a +} +") + +(check-indentation indent-long-if-else-if/3 + " +class Foo { + func a() { + if a { + a + } else if b { + |a + } else if a { + a + } else { + a + } + } +} +" " +class Foo { + func a() { + if a { + a + } else if b { + |a + } else if a { + a + } else { + a + } + } +} +") + +(check-indentation indent-long-if-else-if/4 + " +class Foo { + func a() { + if a { + a + } else if b { + a + |} else if a { + a + } else { + a + } + } +} +" " +class Foo { + func a() { + if a { + a + } else if b { + a + |} else if a { + a + } else { + a + } + } +} +") + +(check-indentation anonymous-function-as-a-argument/1 + " +UIView.animateWithDuration(1.0, + animations: { +|}) +" " +UIView.animateWithDuration(1.0, + animations: { + |}) +") + +(check-indentation anonymous-function-as-a-argument/2 + " +UIView.animateWithDuration( + 1.0, + animations: { +|}) +" " +UIView.animateWithDuration( + 1.0, + animations: { + |}) +") + +(check-indentation anonymous-function-as-a-argument/3 + " +func foo() { + UIView.animateWithDuration(1.0, + animations: { + |} + ) { + completed in + } +} +" " +func foo() { + UIView.animateWithDuration(1.0, + animations: { + |} + ) { + completed in + } +} +") + +(check-indentation anonymous-function-as-a-argument/4 + " +func foo() { + UIView.animateWithDuration(1.0, + animations: { + } +|) { + completed in + } +} +" " +func foo() { + UIView.animateWithDuration(1.0, + animations: { + } + |) { + completed in + } +} +") + +(check-indentation anonymous-function-as-a-argument/5 + " +foo.bar(10, + completionHandler: { complete in + |foo + } +) +" " +foo.bar(10, + completionHandler: { complete in + |foo + } +) +") + +(check-indentation anonymous-function-as-a-argument/6 + " +foo.bar(10, + completionHandler: { + complete in + |foo + } +) +" " +foo.bar(10, + completionHandler: { + complete in + |foo + } +) +") + +(check-indentation anonymous-function-as-a-argument/7 + " +foo.bar(10, + completionHandler: { ( + |bar, baz) in + foo + } +) +" " +foo.bar(10, + completionHandler: { ( + |bar, baz) in + foo + } +) +") + +(check-indentation anonymous-function-as-a-argument/8 + " +foo.bar(10, + completionHandler: { (bar, baz) -> Void in + |foo + } +" " +foo.bar(10, + completionHandler: { (bar, baz) -> Void in + |foo + } +") + +(check-indentation anonymous-function-as-a-argument/9 + " +foo.bar(10, + completionHandler: { complete in + + if foo { + bar + } else { + |bar + } + } +) +" " +foo.bar(10, + completionHandler: { complete in + + if foo { + bar + } else { + |bar + } + } +) +") + +(check-indentation anonymous-function-as-a-argument/10 + " +foo.bar(10, + completionHandler: { complete in + + if foo { + bar + } else { + bar + |} + } +) +" " +foo.bar(10, + completionHandler: { complete in + + if foo { + bar + } else { + bar + |} + } +) +") + +(check-indentation indents-expression-with-optional-type/1 + " +var object: JsonObject? + |var object: JsonObject +" " +var object: JsonObject? +|var object: JsonObject +") + +(check-indentation indents-expression-with-optional-type/2 + " +var object: JsonObject<Foo>? + |var object: JsonObject +" " +var object: JsonObject<Foo>? +|var object: JsonObject +") + +(check-indentation indents-expression-with-implicit-unwrapped-type/1 + " +var object: JsonObject! + |var object: JsonObject +" " +var object: JsonObject! +|var object: JsonObject +") + +(check-indentation indents-expression-with-implicit-unwrapped-type/2 + " +var object: JsonObject<Foo>! + |var object: JsonObject +" " +var object: JsonObject<Foo>! +|var object: JsonObject +") + +(check-indentation indents-expression-with-comment/1 + " +func foo() { + foo() // foo + |foo() +} +" " +func foo() { + foo() // foo + |foo() +} +") + +(check-indentation indents-expression-with-comment/2 + " +func foo() { + let x = 1 // foo + |/ 1 +} +" " +func foo() { + let x = 1 // foo + |/ 1 +} +") (provide 'indentation-tests)