@@ -5163,6 +5163,18 @@ func (c *blankLineBatchContext) initConditions() {
51635163}
51645164
51655165func (c * blankLineBatchContext ) maybeInsertBlankBefore (n ast.Node ) {
5166+ c .maybeInsertBlankBeforeNode (n , true )
5167+ }
5168+
5169+ func (c * blankLineBatchContext ) maybeInsertBlankBeforeClause (n ast.Node ) {
5170+ c .maybeInsertBlankBeforeNode (
5171+ n , shouldAttachLeadingCommentsForClause (c .ctx , n ),
5172+ )
5173+ }
5174+
5175+ func (c * blankLineBatchContext ) maybeInsertBlankBeforeNode (n ast.Node ,
5176+ attachLeadingComments bool ) {
5177+
51665178 if n == nil {
51675179 return
51685180 }
@@ -5171,7 +5183,9 @@ func (c *blankLineBatchContext) maybeInsertBlankBefore(n ast.Node) {
51715183 return
51725184 }
51735185 ls := lineStart (c .ctx .Source , start )
5174- ls = leadingCommentBlockLineStart (c .ctx .Source , ls )
5186+ if attachLeadingComments {
5187+ ls = leadingCommentBlockLineStart (c .ctx .Source , ls )
5188+ }
51755189 if ls <= 0 || hasBlankLineBeforeLineStart (c .ctx .Source , ls ) {
51765190 return
51775191 }
@@ -5191,7 +5205,13 @@ func (c *blankLineBatchContext) inspectFile(file *ast.File) {
51915205 case * ast.CaseClause :
51925206 c .maybeRemoveBlankAfterSingleLineBlockHeader (n )
51935207 if c .caseCond .Eval (caps , c .ctx ) {
5194- c .maybeInsertBlankBefore (n )
5208+ c .maybeInsertBlankBeforeClause (n )
5209+ }
5210+
5211+ case * ast.CommClause :
5212+ c .maybeRemoveBlankAfterSingleLineBlockHeader (n )
5213+ if c .caseCond .Eval (caps , c .ctx ) {
5214+ c .maybeInsertBlankBeforeClause (n )
51955215 }
51965216
51975217 case * ast.ReturnStmt :
@@ -5275,6 +5295,14 @@ func (c *blankLineBatchContext) maybeRemoveBlankAfterSingleLineBlockHeader(
52755295 headerStart = c .ctx .Fset .Position (n .Pos ())
52765296 headerEnd = c .ctx .Fset .Position (n .Colon )
52775297
5298+ case * ast.CommClause :
5299+ if n == nil || len (n .Body ) == 0 {
5300+ return
5301+ }
5302+ first = n .Body [0 ]
5303+ headerStart = c .ctx .Fset .Position (n .Pos ())
5304+ headerEnd = c .ctx .Fset .Position (n .Colon )
5305+
52785306 default :
52795307 return
52805308 }
@@ -5468,6 +5496,79 @@ func (a *InsertBlankBeforeAction) Execute(caps Captures, ctx *Context) ([]byte,
54685496 return out , true
54695497}
54705498
5499+ // InsertBlankBeforeClauseAction inserts a blank line before a switch/select
5500+ // clause label.
5501+ type InsertBlankBeforeClauseAction struct {
5502+ Target string
5503+ }
5504+
5505+ // Execute implements Action for InsertBlankBeforeClauseAction.
5506+ func (a * InsertBlankBeforeClauseAction ) Execute (caps Captures , ctx * Context ) (
5507+ []byte , bool ) {
5508+
5509+ node := resolveTarget (caps , a .Target )
5510+ if node == nil {
5511+ return nil , false
5512+ }
5513+
5514+ pos := ctx .Fset .Position (node .Pos ())
5515+ ls := lineStart (ctx .Source , pos .Offset )
5516+ if shouldAttachLeadingCommentsForClause (ctx , node ) {
5517+ ls = leadingCommentBlockLineStart (ctx .Source , ls )
5518+ }
5519+ if hasBlankLineBeforeLineStart (ctx .Source , ls ) {
5520+ return nil , false
5521+ }
5522+
5523+ out , err := ApplySingleEdit (ctx .Source , ls , ls , []byte ("\n " ))
5524+ if err != nil {
5525+ return nil , false
5526+ }
5527+
5528+ return out , true
5529+ }
5530+
5531+ func shouldAttachLeadingCommentsForClause (ctx * Context , node ast.Node ) bool {
5532+ parent , ok := ctx .Parent (node ).(* ast.BlockStmt )
5533+ if ! ok || parent == nil {
5534+ return true
5535+ }
5536+
5537+ for i , stmt := range parent .List {
5538+ if stmt != node {
5539+ continue
5540+ }
5541+ if i == 0 {
5542+ return true
5543+ }
5544+
5545+ return clauseBodyLen (parent .List [i - 1 ]) > 0
5546+ }
5547+
5548+ return true
5549+ }
5550+
5551+ func clauseBodyLen (stmt ast.Stmt ) int {
5552+ switch n := stmt .(type ) {
5553+ case * ast.CaseClause :
5554+ if n == nil {
5555+ return 0
5556+ }
5557+
5558+ return len (n .Body )
5559+
5560+ case * ast.CommClause :
5561+ if n == nil {
5562+ return 0
5563+ }
5564+
5565+ return len (n .Body )
5566+
5567+ default :
5568+ return 0
5569+ }
5570+ }
5571+
54715572// InsertBlankAfterAction inserts a blank line after a node if not already
54725573// present.
54735574type InsertBlankAfterAction struct {
0 commit comments