Repository: bombsimon/wsl (go)

Issue:
Separate case blocks and other blocks for whitespaces
Blocks cannot start or end with a whitespace. I think this is a very reasonable rule except for maybe the possibility to end a `case` block with a whitespace. I'm open to the idea to at least have this configurable and maybe even as the default since this can actually improve readability and mark where the next case starts. For this to be reasonable it's important to ensure this **does not** apply to the last `case` since that would actually mena the ending of the `switch` block and not the `case` block.

```go
[token] {
    // Can't be a whitespace here
    fmt.Println("...")
    // Can't be a whitespace here
}

switch {
// Can't be a whitespace here
case 1:
    // Can't be a whitespace here
    fmt.Println("...")
    // Can't be a whitespace here - should it be possible?
case 2:
    // Can't be a whitespace here
    fmt.Println("...")
    // Can't be a whitespace here - should it be possible?
case 3:
    // Can't be a whitespace here
    fmt.Println("...")
// Can't be a whitespace here
}
```

Pull request description:
Option to allow trailing whitespace in case blocks
Add configuration (or flag) to allow trailing whitespace in case block.

With this set to true, the following will be allowed:

```go
switch {
case 1:
	fmt.Println("...")

case 2:
	fmt.Println("...")

case 3:
	fmt.Println("...")
}
```
Resolves #25 

Patch:
diff --git a/cmd/wsl/main.go b/cmd/wsl/main.go
index e699f41..e75c7d5 100644
--- a/cmd/wsl/main.go
+++ b/cmd/wsl/main.go
@@ -10,6 +10,7 @@ import (
 	"github.com/bombsimon/wsl"
 )
 
+// nolint: gocognit
 func main() {
 	var (
 		args         []string
@@ -32,6 +33,7 @@ func main() {
 	flag.BoolVar(&config.StrictAppend, "strict-append", true, "Strict rules for append")
 	flag.BoolVar(&config.AllowAssignAndCallCuddle, "allow-assign-and-call", true, "Allow assignments and calls to be cuddled (if using same variable/type)")
 	flag.BoolVar(&config.AllowMultiLineAssignCuddle, "allow-multi-line-assign", true, "Allow cuddling with multi line assignments")
+	flag.BoolVar(&config.AllowCaseTrailingWhitespace, "allow-case-trailing-whitespace", false, "Allow case statements to end with an empty line")
 
 	flag.Parse()
 
diff --git a/wsl.go b/wsl.go
index eb98deb..f5be213 100644
--- a/wsl.go
+++ b/wsl.go
@@ -49,6 +49,22 @@ type Configuration struct {
 	//  }
 	AllowMultiLineAssignCuddle bool
 
+	// AllowCaseTrailingWhitespace will allow case blocks to end with a
+	// whitespace. Sometimes this might actually improve readability. This
+	// defaults to false but setting it to true will enable the following
+	// example:
+	//  switch {
+	//  case 1:
+	//      fmt.Println(1)
+	//
+	// case 2:
+	//     fmt.Println(2)
+	//
+	// case 3:
+	//     fmt:println(3)
+	// }
+	AllowCaseTrailingWhitespace bool
+
 	// AllowCuddleWithCalls is a list of call idents that everything can be
 	// cuddled with. Defaults to calls looking like locks to support a flow like
 	// this:
@@ -69,11 +85,12 @@ type Configuration struct {
 // DefaultConfig returns default configuration
 func DefaultConfig() Configuration {
 	return Configuration{
-		StrictAppend:               true,
-		AllowAssignAndCallCuddle:   true,
-		AllowMultiLineAssignCuddle: true,
-		AllowCuddleWithCalls:       []string{"Lock", "RLock"},
-		AllowCuddleWithRHS:         []string{"Unlock", "RUnlock"},
+		StrictAppend:                true,
+		AllowAssignAndCallCuddle:    true,
+		AllowMultiLineAssignCuddle:  true,
+		AllowCaseTrailingWhitespace: false,
+		AllowCuddleWithCalls:        []string{"Lock", "RLock"},
+		AllowCuddleWithRHS:          []string{"Unlock", "RUnlock"},
 	}
 }
 
@@ -813,6 +830,11 @@ func (p *Processor) findLeadingAndTrailingWhitespaces(stmt, nextStatement ast.No
 			return
 		}
 
+		// If we allow case to end white whitespace just return.
+		if p.config.AllowCaseTrailingWhitespace {
+			return
+		}
+
 		switch n := nextStatement.(type) {
 		case *ast.CaseClause:
 			blockEndPos = n.Case


Test patch:
diff --git a/wsl_test.go b/wsl_test.go
index ae8a5ab..ad8fce5 100644
--- a/wsl_test.go
+++ b/wsl_test.go
@@ -1167,6 +1167,27 @@ func TestWithConfig(t *testing.T) {
 			},
 			expectedErrorStrings: []string{"append only allowed to cuddle with appended value"},
 		},
+		{
+			description: "allow case ending whitespace",
+			code: []byte(`package main
+
+			func main() {
+				switch {
+				case 1:
+					fmt.Println(1)
+
+				case 2:
+					fmt.Println(1)
+
+				case 3:
+					// Still not allowed to end this block with a whitespace.
+					fmt.Println(1)
+				}
+			}`),
+			customConfig: &Configuration{
+				AllowCaseTrailingWhitespace: true,
+			},
+		},
 	}
 
 	for _, tc := range cases {