Skip to content

Commit fdc1545

Browse files
Muir Manderspsanford
authored andcommitted
Fix indent for case statement comments
Try to replicate gofmt behavior. In particular (assuming there are no non-comment lines between comment in question and proceeding "case"): - comments above first "case" always align with case - comments between a case-aligned comment and the proceeding "case" always align with the "case" - all other cases are ambiguous, so if comment is aligned with "case" or with the case block, maintain the indent, otherwise default indent to the case block Closes: #287 [via git-merge-pr]
1 parent 1fcf76d commit fdc1545

File tree

2 files changed

+98
-6
lines changed

2 files changed

+98
-6
lines changed

go-mode.el

Lines changed: 64 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -755,6 +755,60 @@ The return value is the position of the opening paren."
755755
(t
756756
(current-indentation))))))
757757

758+
(defconst go--comment-start-regexp "[[:space:]]*\\(/\\*\\|//\\)")
759+
760+
(defun go--case-comment-p (indent)
761+
"Return non-nil if looking at a comment attached to a case statement.
762+
763+
INDENT is the normal indent of this line, i.e. that of the case body."
764+
(when (looking-at go--comment-start-regexp)
765+
(let (switch-before
766+
case-after
767+
has-case-aligned-preceding-comment)
768+
769+
(save-excursion
770+
;; Search for previous case-aligned comment.
771+
(while (and
772+
(zerop (forward-line -1))
773+
(cond
774+
((go-in-comment-p))
775+
776+
((looking-at "^[[:space:]]*$"))
777+
778+
((looking-at go--comment-start-regexp)
779+
(when (= (current-indentation) (- indent tab-width))
780+
(setq has-case-aligned-preceding-comment t))
781+
t))))
782+
783+
;; Record if a switch (or select) precedes us.
784+
(setq switch-before (looking-at "^[[:space:]]*\\(switch\\|select\\)[[:space:]]")))
785+
786+
;; Record if first proceeding non-comment line is a case statement.
787+
(save-excursion
788+
(while (and
789+
(zerop (forward-line 1))
790+
(or
791+
(go-in-comment-p)
792+
(looking-at go--comment-start-regexp)
793+
(looking-at "^[[:space:]]*$"))))
794+
795+
(setq case-after (looking-at go--case-or-default-regexp)))
796+
797+
(and
798+
;; a "case" statement comes after our comment
799+
case-after
800+
801+
(or
802+
;; "switch" statement precedes us, always align with "case"
803+
switch-before
804+
805+
;; a preceding comment is aligned with "case", we should too
806+
has-case-aligned-preceding-comment
807+
808+
;; other cases are ambiguous, so if comment is currently
809+
;; aligned with "case", leave it that way
810+
(= (current-indentation) (- indent tab-width)))))))
811+
758812
(defun go--non-dangling-indent ()
759813
(save-excursion
760814
(while (go-previous-line-has-dangling-op-p)
@@ -777,12 +831,16 @@ The return value is the position of the opening paren."
777831
(if (go-in-string-or-comment-p)
778832
(goto-char point)
779833
(setq indent (go-indentation-at-point))
780-
(if (and
781-
(looking-at (concat go-label-regexp ":\\([[:space:]]*/.+\\)?$\\|" go--case-or-default-regexp))
782-
;; don't think last part of multiline case statement is a label
783-
(not (go-previous-line-has-dangling-op-p))
784-
(not (go--in-case-clause-list-p)))
785-
(cl-decf indent tab-width))
834+
(when (or
835+
(and
836+
(looking-at (concat go-label-regexp ":\\([[:space:]]*/.+\\)?$\\|" go--case-or-default-regexp))
837+
;; don't think last part of multiline case statement is a label
838+
(not (go-previous-line-has-dangling-op-p))
839+
(not (go--in-case-clause-list-p)))
840+
841+
;; comment attached above a "case" statement
842+
(go--case-comment-p indent))
843+
(cl-decf indent tab-width))
786844
(setq shift-amt (- indent (current-column)))
787845
(if (zerop shift-amt)
788846
nil

test/testdata/indentation_tests/switch.go

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,4 +29,38 @@ func main() {
2929
"hi",
3030
"there":
3131
}
32+
33+
switch {
34+
// attached
35+
case true:
36+
// body
37+
code()
38+
// could go either way
39+
case true:
40+
// could go either way
41+
case true:
42+
// could go both ways
43+
// could go both ways
44+
case true:
45+
46+
/* this works too */
47+
case true:
48+
49+
/* hi */
50+
/* this works too */
51+
case true:
52+
53+
/* hi
54+
this works too */
55+
case true:
56+
57+
// could go either way
58+
case true:
59+
60+
// could go either way
61+
case true:
62+
63+
// also works
64+
default:
65+
}
3266
}

0 commit comments

Comments
 (0)