emacs-elpa-diffs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[nongnu] elpa/go-mode 3ba1982 427/495: Handle indentation for nested dan


From: ELPA Syncer
Subject: [nongnu] elpa/go-mode 3ba1982 427/495: Handle indentation for nested dangling operators
Date: Sat, 7 Aug 2021 09:06:02 -0400 (EDT)

branch: elpa/go-mode
commit 3ba198280bf8d5f2a4079618abfd3db2ebe04f58
Author: Muir Manders <muir@retailnext.net>
Commit: Peter Sanford <psanford@sanford.io>

    Handle indentation for nested dangling operators
    
    The dangling indent level increases for nested dangling expressions:
    
    foo ||
      (bar ||
        baz)
    
    Previously we only allowed a single extra indent from dangling
    operators. Now when indenting the line after a dangling operator we
    use the newly added go--dangling-line-opens-indent-p to determine if
    the dangling line opened a new indent level.
    
    foo ||
      (bar ||
      baz)
    
    is now indented properly as
    
    foo ||
      (bar ||
        baz)
    
    When indenting the statement following the final dangling line we go
    back to the first non-dangling line to determine the indent. For
    example, in cases like:
    
    if foo ||
         (bar ||
           baz) {
      // now we indent here
        // instead of here
    }
    
    Closes: #279 [via git-merge-pr]
---
 go-mode.el                                         | 85 +++++++++++++++++-----
 .../indentation_tests/dangling_operator.go         |  5 ++
 test/testdata/indentation_tests/multiline_if.go    | 53 +++++++++++++-
 3 files changed, 119 insertions(+), 24 deletions(-)

diff --git a/go-mode.el b/go-mode.el
index 009f349..f1b467d 100644
--- a/go-mode.el
+++ b/go-mode.el
@@ -591,20 +591,58 @@ current line will be returned."
           (current-indentation))
       (current-indentation))))
 
-(defun go--line-opens-paren-p ()
-  "Returns whether current line opens a paren that contains point."
+(defun go--dangling-line-opens-indent-p ()
+  "Return non-nil if current dangling line indents the following line."
   (save-excursion
-    (let ((start-paren-level (go-paren-level))
-          (line-beginning (line-beginning-position)))
+    (let ((line-begin (line-beginning-position))
+          (start-paren-level (go-paren-level)))
+
       (go-goto-opening-parenthesis)
-      (and
-       (eq (char-after) ?\() ; opening paren-like character is actually a paren
-       (< (go-paren-level) start-paren-level) ; point is before the closing 
paren
-       (>= (point) line-beginning))))) ; still on starting line
+
+      (let ((in-parens (and
+                        ;; opening paren-like character is actually a paren
+                        (eq (char-after) ?\()
+                        ;; point is before the closing paren
+                        (< (go-paren-level) start-paren-level)
+                        ;;  still on starting line
+                        (>= (point) line-begin))))
+
+        (if (not in-parens)
+            ;; if line doesn't open a paren, check if we are a dangling line 
under
+            ;; a dangling assignment with nothing on RHS of "="
+            ;;
+            ;; foo :=
+            ;;   bar ||   // check if we are this line (need to open indent)
+            ;;     baz ||
+            ;;     qux
+            (progn
+              (goto-char line-begin)
+              (let ((prev-line (go-previous-line-has-dangling-op-p)))
+                (when prev-line
+                  (goto-char prev-line)
+                  (and
+                   (not (go-previous-line-has-dangling-op-p))
+                   (looking-at ".*=[[:space:]]*$")))))
+          (or
+           ;; previous line is dangling and opens indent
+           (let ((prev-line (go-previous-line-has-dangling-op-p)))
+             (when prev-line
+               (save-excursion
+                 (goto-char prev-line)
+                 (end-of-line)
+                 (go--dangling-line-opens-indent-p))))
+
+           ;; or paren is only preceded by identifier or other parens
+           (string-match-p "^[[:space:]]*[[:word:][:multibyte:]]*(*$" 
(buffer-substring line-begin (point)))
+
+           ;; or a preceding paren on this line opens an indent
+           (and
+            (> (point) line-begin)
+            (progn (backward-char) (go--dangling-line-opens-indent-p)))))))))
 
 (defun go-indentation-at-point ()
   (save-excursion
-    (let (start-nesting)
+    (let (start-nesting dangling-line)
       (back-to-indentation)
       (setq start-nesting (go-paren-level))
 
@@ -614,31 +652,38 @@ current line will be returned."
        ((looking-at "[])}]")
         (go-goto-opening-parenthesis)
         (if (and
-             (not (eq (char-after) ?\()) ; opening parens always indent
+             (not (eq (char-after) ?\())
              (go-previous-line-has-dangling-op-p))
-            (- (current-indentation) tab-width)
+            (go--non-dangling-indent)
           (go--indentation-for-opening-parenthesis)))
-       ((progn (go--backward-irrelevant t)
-               (looking-back go-dangling-operators-regexp
-                             (- (point) go--max-dangling-operator-length)))
+       ((setq dangling-line (go-previous-line-has-dangling-op-p))
+        (goto-char dangling-line)
+        (end-of-line)
+
         ;; only one nesting for all dangling operators in one operation
         (if (and
-             (not (go--line-opens-paren-p))
+             (not (go--dangling-line-opens-indent-p))
              (go-previous-line-has-dangling-op-p))
-            (progn
-              (current-indentation))
+            (current-indentation)
           (+ (current-indentation) tab-width)))
        ((zerop (go-paren-level))
         0)
        ((progn (go-goto-opening-parenthesis) (< (go-paren-level) 
start-nesting))
         (if (and
-             (not (eq (char-after) ?\()) ; opening parens always indent
+             (not (eq (char-after) ?\())
              (go-previous-line-has-dangling-op-p))
-            (current-indentation)
-          (+ (go--indentation-for-opening-parenthesis) tab-width)))
+            (+ (go--non-dangling-indent) tab-width)
+          (+ (go--indentation-for-opening-parenthesis) tab-width))
+        )
        (t
         (current-indentation))))))
 
+(defun go--non-dangling-indent ()
+  (save-excursion
+    (while (go-previous-line-has-dangling-op-p)
+      (forward-line -1))
+    (current-indentation)))
+
 (defun go-mode-indent-line ()
   (interactive)
   (let (indent
diff --git a/test/testdata/indentation_tests/dangling_operator.go 
b/test/testdata/indentation_tests/dangling_operator.go
index 6eff406..281ea53 100644
--- a/test/testdata/indentation_tests/dangling_operator.go
+++ b/test/testdata/indentation_tests/dangling_operator.go
@@ -35,5 +35,10 @@ func init() {
                        3 *
                        1)
 
+       i :=
+               "" != "" ||
+                       true == false ||
+                       false == false
+
        return
 }
diff --git a/test/testdata/indentation_tests/multiline_if.go 
b/test/testdata/indentation_tests/multiline_if.go
index 410704d..d73ae74 100644
--- a/test/testdata/indentation_tests/multiline_if.go
+++ b/test/testdata/indentation_tests/multiline_if.go
@@ -1,5 +1,50 @@
-if realLength == -1 &&
-       !chunked(t.TransferEncoding) &&
-       bodyAllowedForStatus(t.StatusCode) {
-       t.Close = true
+package foo
+
+import (
+       "bytes"
+       "errors"
+)
+
+func _() {
+       if realLength == -1 &&
+               !chunked(t.TransferEncoding) &&
+               bodyAllowedForStatus(t.StatusCode) {
+               t.Close = true
+       }
+
+       if true &&
+               (true ||
+                       true && (true ||
+                               false) && true) {
+               true
+       }
+
+       if true && (true &&
+               true) {
+               true
+       }
+
+       if true &&
+               (true && (true ||
+                       false) && true) {
+               true
+       }
+
+       if true &&
+               foo(true &&
+                       true) {
+               true
+       }
+
+       if true &&
+               true && (true ||
+               true) {
+               true
+       }
+
+       if bytes.Contains(out, []byte("-fsanitize")) &&
+               (bytes.Contains(out, []byte("unrecognized")) ||
+                       bytes.Contains(out, []byte("unsupported"))) {
+               return true, errors.New(string(out))
+       }
 }



reply via email to

[Prev in Thread] Current Thread [Next in Thread]