Skip to content

Commit

Permalink
indent: fix func literals in dangling lines
Browse files Browse the repository at this point in the history
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 dominikh#332.

Closes: dominikh#333 [via git-merge-pr]
  • Loading branch information
muirdm authored and psanford committed Jan 7, 2020
1 parent 7c38d6a commit e10d677
Show file tree
Hide file tree
Showing 2 changed files with 59 additions and 8 deletions.
51 changes: 43 additions & 8 deletions go-mode.el
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down Expand Up @@ -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
Expand All @@ -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
Expand Down Expand Up @@ -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.
Expand Down Expand Up @@ -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))
Expand Down
16 changes: 16 additions & 0 deletions test/testdata/indentation_tests/function_call.go
Original file line number Diff line number Diff line change
Expand Up @@ -61,4 +61,20 @@ func _() {
1,
),
)

foo.
bar(func(i int) (a b) {

})

foo ||
bar &&
baz(func() {
X
})

foo &&
func() bool {
return X
}()
}

0 comments on commit e10d677

Please sign in to comment.