Skip to content

Commit 29759f5

Browse files
committed
Fix indentation of generic-parameter-clause
Example: ``` struct Foo< A: A, A: A, A: A > { } ``` Closes #164.
1 parent 1268425 commit 29759f5

File tree

4 files changed

+221
-6
lines changed

4 files changed

+221
-6
lines changed

swift-mode-indent.el

Lines changed: 26 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -316,6 +316,16 @@ declaration and its offset is `swift-mode:basic-offset'."
316316
(backward-list)
317317
(swift-mode:calculate-indent-of-expression 0))
318318

319+
;; Before > as a close angle bracket on the current line
320+
((and next-is-on-current-line
321+
(save-excursion
322+
(goto-char (swift-mode:token:start next-token))
323+
(and (eq (char-after) ?>)
324+
(progn (swift-mode:try-backward-generic-parameters)
325+
(< (point) (swift-mode:token:start next-token))))))
326+
(swift-mode:try-backward-generic-parameters)
327+
(swift-mode:calculate-indent-of-expression 0))
328+
319329
;; Before end of a interpolated expression on the current line
320330
((and next-is-on-current-line
321331
(eq next-type 'string-chunk-after-interpolated-expression))
@@ -425,8 +435,8 @@ declaration and its offset is `swift-mode:basic-offset'."
425435
(swift-mode:calculate-indent-after-open-curly-brace
426436
swift-mode:basic-offset))
427437

428-
;; After ( or [
429-
((memq previous-type '(\( \[))
438+
;; After (, [, or < as a open angle bracket
439+
((memq previous-type '(\( \[ <))
430440
(goto-char (swift-mode:token:start previous-token))
431441
(swift-mode:calculate-indent-of-expression
432442
swift-mode:parenthesized-expression-offset
@@ -830,7 +840,7 @@ the expression."
830840
(defun swift-mode:calculate-indent-after-open-curly-brace (offset)
831841
"Return indentation after open curly braces.
832842
833-
Assuming the cursor is on the open parenthesis.
843+
Assuming the cursor is on the open brace.
834844
OFFSET is the offset of the contents.
835845
This function is also used for close-curly-brace."
836846
;; If the statement is multiline expression, aligns with the start of
@@ -883,11 +893,22 @@ This function is also used for close-curly-brace."
883893
;; // The body of the for-statement.
884894
;; }
885895
(let ((pos (point))
896+
previous-token
886897
next-token
887898
is-declaration-or-control-statement-body)
888899
(if (save-excursion
889-
(eq (swift-mode:token:type (swift-mode:backward-token))
890-
'binary-operator))
900+
(setq previous-token (swift-mode:backward-token))
901+
(and (eq (swift-mode:token:type previous-token) 'binary-operator)
902+
;; not > as close angle bracket
903+
(not
904+
(progn
905+
(goto-char (swift-mode:token:end previous-token))
906+
(and (eq (char-before) ?>)
907+
(progn
908+
(backward-char)
909+
(swift-mode:try-backward-generic-parameters)
910+
(< (point)
911+
(1- (swift-mode:token:end previous-token)))))))))
891912
;; for x in
892913
;; xs
893914
;; +++ { x in

swift-mode-lexer.el

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -408,6 +408,16 @@ Return nil otherwise."
408408
(memq (swift-mode:token:type previous-token) '({ \( \[))
409409
(memq (swift-mode:token:type next-token) '(} \) \]))
410410

411+
;; Supress implicit semicolon before/after open angle bracket.
412+
(and (equal (swift-mode:token:text previous-token) "<")
413+
(save-excursion
414+
(goto-char (swift-mode:token:start previous-token))
415+
(swift-mode:generic-parameter-clause-start-p)))
416+
(and (equal (swift-mode:token:text next-token) "<")
417+
(save-excursion
418+
(goto-char (swift-mode:token:start next-token))
419+
(swift-mode:generic-parameter-clause-start-p)))
420+
411421
;; Suppress implicit semicolon after/before string chunks inside
412422
;; interpolated expressions.
413423
(eq (swift-mode:token:type previous-token)
@@ -720,6 +730,16 @@ Return nil otherwise."
720730
'(\; { \( \[ "for")))
721731
'{)))
722732

733+
(defun swift-mode:generic-parameter-clause-start-p ()
734+
"Return t if the `<' at the cursor is a start of generic parameters.
735+
736+
Return nil otherwise."
737+
(save-excursion
738+
(or (member (swift-mode:token:text (swift-mode:backward-token-simple))
739+
'("init" "subscript"))
740+
(member (swift-mode:token:text (swift-mode:backward-token-simple))
741+
'("typealias" "func" "enum" "struct" "class" "init")))))
742+
723743
(defun swift-mode:fix-operator-type (token)
724744
"Return new operator token with proper token type.
725745
@@ -819,6 +839,15 @@ type `outside-of-buffer'."
819839
(progn (forward-char) (1- (point)))
820840
(point)))
821841

842+
;; Start of generic-parameter-clause
843+
((and
844+
(eq (char-after) ?<)
845+
(swift-mode:generic-parameter-clause-start-p))
846+
(swift-mode:token '<
847+
"<"
848+
(progn (forward-char) (1- (point)))
849+
(point)))
850+
822851
(t
823852
(let ((token (swift-mode:forward-token-simple)))
824853
(setq token (swift-mode:backquote-identifier-if-after-dot token))
@@ -1032,6 +1061,18 @@ type `outside-of-buffer'."
10321061
(point)
10331062
(1+ (point))))
10341063

1064+
;; Start of generic-parameter-clause
1065+
((and
1066+
(eq (char-before) ?<)
1067+
(save-excursion
1068+
(backward-char)
1069+
(swift-mode:generic-parameter-clause-start-p)))
1070+
(backward-char)
1071+
(swift-mode:token '<
1072+
"<"
1073+
(point)
1074+
(1+ (point))))
1075+
10351076
(t
10361077
(let ((token (swift-mode:backward-token-simple)))
10371078
(setq token (swift-mode:backquote-identifier-if-after-dot token))

test/swift-files/indent/declarations.swift

Lines changed: 153 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -248,6 +248,50 @@ class Foo {
248248
=
249249
C
250250
.D
251+
252+
typealias Foo<
253+
A: A,
254+
A: A, A: A
255+
> =
256+
A
257+
258+
typealias Foo<
259+
A: A,
260+
A: A, A: A> =
261+
A
262+
263+
typealias Foo <A: A,
264+
A: A, A: A> =
265+
A
266+
267+
typealias Foo <A: A,
268+
A: A, A: A
269+
> =
270+
A
271+
272+
typealias Foo
273+
<
274+
A: A,
275+
A: A, A: A
276+
> =
277+
A
278+
279+
typealias Foo
280+
<
281+
A: A,
282+
A: A, A: A> =
283+
A
284+
285+
typealias Foo
286+
<A: A,
287+
A: A, A: A> =
288+
A
289+
290+
typealias Foo
291+
<A: A,
292+
A: A, A: A
293+
> =
294+
A
251295
}
252296

253297
// Function declarations
@@ -300,6 +344,71 @@ func
300344
foo()
301345
}
302346

347+
func foo<
348+
A: A,
349+
A: A, A: A
350+
> (
351+
a: A,
352+
a: A
353+
){
354+
}
355+
356+
func foo<
357+
A: A,
358+
A: A, A: A> (
359+
a: A,
360+
a: A) {
361+
}
362+
363+
func foo<A: A,
364+
A: A, A: A> (a: A,
365+
a: A) {
366+
}
367+
368+
func foo<A: A,
369+
A: A, A: A
370+
> (
371+
a: A,
372+
a: A
373+
) {
374+
}
375+
376+
func foo
377+
<
378+
A: A,
379+
A: A, A: A
380+
>
381+
(
382+
a: A,
383+
a: A
384+
){
385+
}
386+
387+
func foo
388+
<
389+
A: A,
390+
A: A, A: A>
391+
(
392+
a: A,
393+
a: A) {
394+
}
395+
396+
func foo
397+
<A: A,
398+
A: A, A: A>
399+
(a: A,
400+
a: A) {
401+
}
402+
403+
func foo
404+
<A: A,
405+
A: A, A: A
406+
>
407+
(a: A,
408+
a: A
409+
) {
410+
}
411+
303412
// Enumeration declarations
304413

305414
fileprivate
@@ -417,6 +526,50 @@ struct A {
417526
}
418527
}
419528

529+
struct Foo<
530+
A: A,
531+
A: A, A: A
532+
> {
533+
}
534+
535+
struct Foo<
536+
A: A,
537+
A: A, A: A> {
538+
}
539+
540+
struct Foo<A: A,
541+
A: A, A: A> {
542+
}
543+
544+
struct Foo<A: A,
545+
A: A, A: A
546+
> {
547+
}
548+
549+
struct Foo
550+
<
551+
A: A,
552+
A: A, A: A
553+
> {
554+
}
555+
556+
struct Foo
557+
<
558+
A: A,
559+
A: A, A: A> {
560+
}
561+
562+
struct Foo
563+
<A: A,
564+
A: A, A: A> {
565+
}
566+
567+
struct Foo
568+
<A: A,
569+
A: A, A: A
570+
> {
571+
}
572+
420573
// Protocol declarations
421574

422575
protocol Foo {

test/swift-files/indent/types.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -282,5 +282,5 @@ let foo: protocol<A<[B]>,
282282
let foo: protocol<
283283
A, // swift-mode:test:known-bug
284284
B
285-
> // swift-mode:test:known-bug
285+
>
286286
= a

0 commit comments

Comments
 (0)