branch: elpa/go-mode
commit 1650ae5f2343feb313703c4949079ae601fe1bd5
Author: Muir Manders <[email protected]>
Commit: Peter Sanford <[email protected]>

    Fix multiline case statement indent.
    
    Now that we support commas as dangling operators, expand the
    "case foo:" regex to match across lines.
    
    Also handle the case where there is a newline directly after the
    "case" keyword. We now don't treat commas as dangling operators in
    "case" clause lists.
    
    Fixes #280
---
 go-mode.el                                | 36 ++++++++++++++++++++++++++++++-
 test/testdata/indentation_tests/switch.go | 19 ++++++++++++++++
 2 files changed, 54 insertions(+), 1 deletion(-)

diff --git a/go-mode.el b/go-mode.el
index b5575d2..ca9bd0a 100644
--- a/go-mode.el
+++ b/go-mode.el
@@ -643,8 +643,35 @@ current line will be returned."
   (not (or
         (go--open-paren-position)
         (go--in-composite-literal-p)
+        (go--in-case-clause-list-p)
         (go--in-struct-definition-p))))
 
+(defun go--in-case-clause-list-p ()
+  "Return non-nil if inside a multi-line case cause list.
+
+This function is only concerned with list items on lines after the
+case keyword. It returns nil for the case line itself."
+  (save-excursion
+    (beginning-of-line)
+    (when (not (looking-at go--case-or-default-regexp))
+      (let (saw-colon)
+        ;; optionally skip line with the colon
+        (when (looking-at ".*:[[:space:]]*$")
+          (setq saw-colon t)
+          (forward-line -1))
+
+        ;; go backwards while at a comment or a line ending in comma
+        (while (and
+                (or (go-in-comment-p)
+                    (looking-at 
"[[:space:]]*\\(//\\|/\\*\\)\\|.*,[[:space:]]*$"))
+                (zerop (forward-line -1))))
+
+        (and
+         (looking-at go--case-regexp)
+         ;; we weren't in case list if first line ended in colon
+         ;; and the "case" line ended in colon
+         (not (and saw-colon (looking-at ".*:[[:space:]]*$"))))))))
+
 (defun go--in-struct-definition-p ()
   "Return non-nil if inside a struct definition."
   (save-excursion
@@ -734,6 +761,9 @@ The return value is the position of the opening paren."
       (forward-line -1))
     (current-indentation)))
 
+(defconst go--case-regexp "\\([[:space:]]*case\\([[:space:]]\\|$\\)\\)")
+(defconst go--case-or-default-regexp (concat "\\(" go--case-regexp "\\|"  
"[[:space:]]*default:\\)"))
+
 (defun go-mode-indent-line ()
   (interactive)
   (let (indent
@@ -745,7 +775,11 @@ The return value is the position of the opening paren."
     (if (go-in-string-or-comment-p)
         (goto-char point)
       (setq indent (go-indentation-at-point))
-      (if (looking-at (concat go-label-regexp ":\\([[:space:]]*/.+\\)?$\\|case 
.+:\\|default:"))
+      (if (and
+           (looking-at (concat go-label-regexp ":\\([[:space:]]*/.+\\)?$\\|" 
go--case-or-default-regexp))
+           ;; don't think last part of multiline case statement is a label
+           (not (go-previous-line-has-dangling-op-p))
+           (not (go--in-case-clause-list-p)))
           (cl-decf indent tab-width))
       (setq shift-amt (- indent (current-column)))
       (if (zerop shift-amt)
diff --git a/test/testdata/indentation_tests/switch.go 
b/test/testdata/indentation_tests/switch.go
index 259b293..7d0f972 100644
--- a/test/testdata/indentation_tests/switch.go
+++ b/test/testdata/indentation_tests/switch.go
@@ -3,6 +3,7 @@ package _switch
 func main() {
        switch "" {
        case "foo":
+       label:
                code()
        case "bar":
        case "baz":
@@ -10,4 +11,22 @@ func main() {
        default:
                code()
        }
+
+       switch 123 {
+       case 1, 2,
+               3:
+       case
+               1,
+               3:
+       case
+               // hi
+               "hi",
+               "there":
+               code()
+       case
+               /* hi
+                  there */
+               "hi",
+               "there":
+       }
 }

Reply via email to