branch: elpa/swift-mode commit 29759f529032fff9b88a77318a10b2a1ec8ef5c7 Author: taku0 <mxxouy6x3m_git...@tatapa.org> Commit: taku0 <mxxouy6x3m_git...@tatapa.org>
Fix indentation of generic-parameter-clause Example: ``` struct Foo< A: A, A: A, A: A > { } ``` Closes https://github.com/swift-emacs/swift-mode/issues/164. --- swift-mode-indent.el | 31 +++++- swift-mode-lexer.el | 41 ++++++++ test/swift-files/indent/declarations.swift | 153 +++++++++++++++++++++++++++++ test/swift-files/indent/types.swift | 2 +- 4 files changed, 221 insertions(+), 6 deletions(-) diff --git a/swift-mode-indent.el b/swift-mode-indent.el index dfb59b8..f9b719a 100644 --- a/swift-mode-indent.el +++ b/swift-mode-indent.el @@ -316,6 +316,16 @@ declaration and its offset is `swift-mode:basic-offset'." (backward-list) (swift-mode:calculate-indent-of-expression 0)) + ;; Before > as a close angle bracket on the current line + ((and next-is-on-current-line + (save-excursion + (goto-char (swift-mode:token:start next-token)) + (and (eq (char-after) ?>) + (progn (swift-mode:try-backward-generic-parameters) + (< (point) (swift-mode:token:start next-token)))))) + (swift-mode:try-backward-generic-parameters) + (swift-mode:calculate-indent-of-expression 0)) + ;; Before end of a interpolated expression on the current line ((and next-is-on-current-line (eq next-type 'string-chunk-after-interpolated-expression)) @@ -425,8 +435,8 @@ declaration and its offset is `swift-mode:basic-offset'." (swift-mode:calculate-indent-after-open-curly-brace swift-mode:basic-offset)) - ;; After ( or [ - ((memq previous-type '(\( \[)) + ;; After (, [, or < as a open angle bracket + ((memq previous-type '(\( \[ <)) (goto-char (swift-mode:token:start previous-token)) (swift-mode:calculate-indent-of-expression swift-mode:parenthesized-expression-offset @@ -830,7 +840,7 @@ the expression." (defun swift-mode:calculate-indent-after-open-curly-brace (offset) "Return indentation after open curly braces. -Assuming the cursor is on the open parenthesis. +Assuming the cursor is on the open brace. OFFSET is the offset of the contents. This function is also used for close-curly-brace." ;; If the statement is multiline expression, aligns with the start of @@ -883,11 +893,22 @@ This function is also used for close-curly-brace." ;; // The body of the for-statement. ;; } (let ((pos (point)) + previous-token next-token is-declaration-or-control-statement-body) (if (save-excursion - (eq (swift-mode:token:type (swift-mode:backward-token)) - 'binary-operator)) + (setq previous-token (swift-mode:backward-token)) + (and (eq (swift-mode:token:type previous-token) 'binary-operator) + ;; not > as close angle bracket + (not + (progn + (goto-char (swift-mode:token:end previous-token)) + (and (eq (char-before) ?>) + (progn + (backward-char) + (swift-mode:try-backward-generic-parameters) + (< (point) + (1- (swift-mode:token:end previous-token))))))))) ;; for x in ;; xs ;; +++ { x in diff --git a/swift-mode-lexer.el b/swift-mode-lexer.el index a41d152..11a19b4 100644 --- a/swift-mode-lexer.el +++ b/swift-mode-lexer.el @@ -408,6 +408,16 @@ Return nil otherwise." (memq (swift-mode:token:type previous-token) '({ \( \[)) (memq (swift-mode:token:type next-token) '(} \) \])) + ;; Supress implicit semicolon before/after open angle bracket. + (and (equal (swift-mode:token:text previous-token) "<") + (save-excursion + (goto-char (swift-mode:token:start previous-token)) + (swift-mode:generic-parameter-clause-start-p))) + (and (equal (swift-mode:token:text next-token) "<") + (save-excursion + (goto-char (swift-mode:token:start next-token)) + (swift-mode:generic-parameter-clause-start-p))) + ;; Suppress implicit semicolon after/before string chunks inside ;; interpolated expressions. (eq (swift-mode:token:type previous-token) @@ -720,6 +730,16 @@ Return nil otherwise." '(\; { \( \[ "for"))) '{))) +(defun swift-mode:generic-parameter-clause-start-p () + "Return t if the `<' at the cursor is a start of generic parameters. + +Return nil otherwise." + (save-excursion + (or (member (swift-mode:token:text (swift-mode:backward-token-simple)) + '("init" "subscript")) + (member (swift-mode:token:text (swift-mode:backward-token-simple)) + '("typealias" "func" "enum" "struct" "class" "init"))))) + (defun swift-mode:fix-operator-type (token) "Return new operator token with proper token type. @@ -819,6 +839,15 @@ type `outside-of-buffer'." (progn (forward-char) (1- (point))) (point))) + ;; Start of generic-parameter-clause + ((and + (eq (char-after) ?<) + (swift-mode:generic-parameter-clause-start-p)) + (swift-mode:token '< + "<" + (progn (forward-char) (1- (point))) + (point))) + (t (let ((token (swift-mode:forward-token-simple))) (setq token (swift-mode:backquote-identifier-if-after-dot token)) @@ -1032,6 +1061,18 @@ type `outside-of-buffer'." (point) (1+ (point)))) + ;; Start of generic-parameter-clause + ((and + (eq (char-before) ?<) + (save-excursion + (backward-char) + (swift-mode:generic-parameter-clause-start-p))) + (backward-char) + (swift-mode:token '< + "<" + (point) + (1+ (point)))) + (t (let ((token (swift-mode:backward-token-simple))) (setq token (swift-mode:backquote-identifier-if-after-dot token)) diff --git a/test/swift-files/indent/declarations.swift b/test/swift-files/indent/declarations.swift index 5fda5c8..17dc5b3 100644 --- a/test/swift-files/indent/declarations.swift +++ b/test/swift-files/indent/declarations.swift @@ -248,6 +248,50 @@ class Foo { = C .D + + typealias Foo< + A: A, + A: A, A: A + > = + A + + typealias Foo< + A: A, + A: A, A: A> = + A + + typealias Foo <A: A, + A: A, A: A> = + A + + typealias Foo <A: A, + A: A, A: A + > = + A + + typealias Foo + < + A: A, + A: A, A: A + > = + A + + typealias Foo + < + A: A, + A: A, A: A> = + A + + typealias Foo + <A: A, + A: A, A: A> = + A + + typealias Foo + <A: A, + A: A, A: A + > = + A } // Function declarations @@ -300,6 +344,71 @@ func foo() } +func foo< + A: A, + A: A, A: A +> ( + a: A, + a: A +){ +} + +func foo< + A: A, + A: A, A: A> ( + a: A, + a: A) { +} + +func foo<A: A, + A: A, A: A> (a: A, + a: A) { +} + +func foo<A: A, + A: A, A: A +> ( + a: A, + a: A +) { +} + +func foo + < + A: A, + A: A, A: A + > + ( + a: A, + a: A + ){ +} + +func foo + < + A: A, + A: A, A: A> + ( + a: A, + a: A) { +} + +func foo + <A: A, + A: A, A: A> + (a: A, + a: A) { +} + +func foo + <A: A, + A: A, A: A + > + (a: A, + a: A + ) { +} + // Enumeration declarations fileprivate @@ -417,6 +526,50 @@ struct A { } } +struct Foo< + A: A, + A: A, A: A +> { +} + +struct Foo< + A: A, + A: A, A: A> { +} + +struct Foo<A: A, + A: A, A: A> { +} + +struct Foo<A: A, + A: A, A: A +> { +} + +struct Foo + < + A: A, + A: A, A: A + > { +} + +struct Foo + < + A: A, + A: A, A: A> { +} + +struct Foo + <A: A, + A: A, A: A> { +} + +struct Foo + <A: A, + A: A, A: A + > { +} + // Protocol declarations protocol Foo { diff --git a/test/swift-files/indent/types.swift b/test/swift-files/indent/types.swift index 331a3c9..c9e0ae3 100644 --- a/test/swift-files/indent/types.swift +++ b/test/swift-files/indent/types.swift @@ -282,5 +282,5 @@ let foo: protocol<A<[B]>, let foo: protocol< A, // swift-mode:test:known-bug B -> // swift-mode:test:known-bug +> = a