branch: elpa/go-mode
commit e10d6775f486ef09ed993567b0bd2c69f35deb45
Author: Muir Manders <[email protected]>
Commit: Peter Sanford <[email protected]>
indent: fix func literals in dangling lines
Fix cases like:
foo &&
bar(func() {
X // Bad
})
foo &&
bar(func() {
X // Good
})
When computing indent for "X" we were misinterpreting the enclosing
"{" as a control flow block opener as in:
foo &&
bar {
X
}
Now we better differentiate func literal opening curlies and control
flow block curlies.
Fixes #332.
Closes: #333 [via git-merge-pr]
---
go-mode.el | 51 ++++++++++++++++++++----
test/testdata/indentation_tests/function_call.go | 16 ++++++++
2 files changed, 59 insertions(+), 8 deletions(-)
diff --git a/go-mode.el b/go-mode.el
index 600b6c4..a0b72be 100644
--- a/go-mode.el
+++ b/go-mode.el
@@ -865,7 +865,7 @@ is done."
(first t)
;; Whether we start in a block (i.e. our first line is not a
- ;; continuation line and is in an "if", "for", "func" etc. block).
+ ;; continuation line and is in an "if", "for", etc. block).
(in-block)
;; Our desired indent relative to our ending line's indent.
@@ -942,10 +942,7 @@ is done."
;; If we aren't a continuation line and we have an enclosing paren
;; or brace, jump to opener and increment our indent.
(when (go-goto-opening-parenthesis)
- ;; We started in a child block if our opener is a curly brace.
- (setq in-block (and
- (eq (char-after) ?{)
- (looking-back "[^[:space:]][[:space:]]" (-
(point) 2))))
+ (setq in-block (go--flow-block-p))
(cl-incf indent tab-width))))
;; If we started in a child block we must follow dangling lines
@@ -959,7 +956,8 @@ is done."
;; There can be an arbitrary number of indents, so we must go back to
;; the "if" to determine the indent of "X".
(when (and in-block (bolp) (go-previous-line-has-dangling-op-p))
- (goto-char (go-previous-line-has-dangling-op-p))))
+ (goto-char (go-previous-line-has-dangling-op-p)))
+ )
;; If our ending line is a continuation line but doesn't open
;; an extra indent, reduce indent. We tentatively gave indents to all
@@ -1007,6 +1005,32 @@ are loose binding expression separators."
(|| 1)
(t 0)))
+(defun go--flow-block-p ()
+ "Return whether looking at a { that opens a control flow block.
+
+We check for a { that is preceded by a space and is not a func
+literal opening brace."
+ (save-excursion
+ (when (and
+ (eq (char-after) ?{)
+ (not (zerop (skip-syntax-backward " "))))
+
+ (let ((eol (line-end-position))
+ (level (go-paren-level))
+ (found-func-literal))
+
+ (beginning-of-line)
+
+ ;; See if we find any "func" keywords on this line at the same paren
+ ;; level as the curly.
+ (while (and
+ (not found-func-literal)
+ (re-search-forward "\\_<func\\_>" eol t))
+ (setq found-func-literal (and
+ (= level (go-paren-level))
+ (not (go-in-string-or-comment-p)))))
+ (not found-func-literal)))))
+
(defun go--continuation-line-indents-p ()
"Return non-nil if the current continuation line opens an additional indent.
@@ -1037,8 +1061,19 @@ foo ||
(when (or
;; We can only open indent if we have a dangling operator, or
(go--current-line-has-dangling-op-p)
- ;; we end in an opening paren/brace or comma.
- (go--line-suffix-p "[(,]\\|[^[:space:]]{"))
+
+ (save-excursion
+ (go--end-of-line)
+ (backward-char)
+ (or
+ ;; Line ends in a "(" or ",", or
+ (eq (char-after) ?\()
+ (eq (char-after) ?,)
+
+ ;; Line ends in a "{" that isn't a control block.
+ (and
+ (eq (char-after) ?{)
+ (not (go--flow-block-p))))))
(let ((prev-precedence (go--operator-precedence prev-op))
(start-depth (go-paren-level))
diff --git a/test/testdata/indentation_tests/function_call.go
b/test/testdata/indentation_tests/function_call.go
index 3222bd7..c579a19 100644
--- a/test/testdata/indentation_tests/function_call.go
+++ b/test/testdata/indentation_tests/function_call.go
@@ -61,4 +61,20 @@ func _() {
1,
),
)
+
+ foo.
+ bar(func(i int) (a b) {
+
+ })
+
+ foo ||
+ bar &&
+ baz(func() {
+ X
+ })
+
+ foo &&
+ func() bool {
+ return X
+ }()
}