branch: elpa/go-mode
commit 2f2910c33de85119c026c53f180f7124f68548a9
Author: Erin Keenan <[email protected]>
Commit: Dominik Honnef <[email protected]>
fix end-of-defun for function with inline struct/interface arguments
Closes gh-34
---
go-mode.el | 13 ++++++++--
movement_tests/functions.go | 59 +++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 70 insertions(+), 2 deletions(-)
diff --git a/go-mode.el b/go-mode.el
index 1604e74..e7e6981 100644
--- a/go-mode.el
+++ b/go-mode.el
@@ -548,8 +548,17 @@ current line will be returned."
;; It can happen that we're not placed before a function by emacs
(if (not (looking-at "func"))
(go-beginning-of-defun -1))
- (skip-chars-forward "^{")
- (forward-char)
+ ;; Find the { that starts the function, i.e., the next { that isn't
+ ;; preceded by struct or interface, or a comment or struct tag. BUG:
+ ;; breaks if there's a comment between the struct/interface keyword and
+ ;; bracket, like this:
+ ;;
+ ;; struct /* why? */ {
+ (while (progn
+ (skip-chars-forward "^{")
+ (forward-char)
+ (or (go-in-string-or-comment-p)
+ (looking-back "\\(struct\\|interface\\)\\s-*{"))))
(setq orig-level (go-paren-level))
(while (>= (go-paren-level) orig-level)
(skip-chars-forward "^}")
diff --git a/movement_tests/functions.go b/movement_tests/functions.go
new file mode 100644
index 0000000..40705bc
--- /dev/null
+++ b/movement_tests/functions.go
@@ -0,0 +1,59 @@
+// This file can be used to manually test that go-beginning-of-def and
+// go-end-of-defun are correct by entering into each function and mark-defun
+// (C-M-h).
+package main
+
+type typea int
+
+func easy(a, b, c int) int {
+ c += a
+ c += b
+ return c
+}
+
+func harder(a chan struct{}) {
+ close(a)
+}
+
+func harder(a struct {
+ b struct {
+ c interface {
+ Foo()
+ Bar()
+ Baz()
+ }
+ }
+}) interface {
+ Channer() chan struct{}
+} {
+ return nil
+}
+
+func oneline(a struct{}) (r struct{ a int }) { return r }
+
+type typeb struct {
+ a, b, c int
+}
+
+// comment1 breaks end-of-defun by splitting "struct" from "{". (This also
+// apparently breaks gofmt, is why this is formatted so weird.)
+func comment1(a chan struct /* why? */ {
+
+}) {
+ close(a)
+}
+
+func comment2(a struct {
+ b int // b is sad :{
+ c int
+}) {
+ a.b += a.c
+ a.c += a.b
+ return
+}
+
+func structWithTag(a chan struct {
+ v int `{`
+}) {
+ close(a)
+}