branch: elpa/go-mode
commit b261fac068fd13ac8f02901cccd536702cc894e4
Author: Lowe Thiderman <[email protected]>
Commit: Dominik Honnef <[email protected]>

    Add support for (nested) anonymous functions in go-goto-function
---
 go-mode.el | 90 +++++++++++++++++++++++++++++++++++++++++++++++++-------------
 1 file changed, 71 insertions(+), 19 deletions(-)

diff --git a/go-mode.el b/go-mode.el
index 7e8e527..d513064 100644
--- a/go-mode.el
+++ b/go-mode.el
@@ -1573,22 +1573,68 @@ for."
 
 If we are on a docstring, follow the docstring down.
 If no function is found, assume that we are at the top of a file
-and search forward instead."
-  (interactive)
+and search forward instead.
 
-  (beginning-of-line)
-  (cond
-   ((looking-at "^//")
-    ;; In case we are looking at the docstring, move on forward until we are 
not anymore
-    (while (looking-at "^//")
-      (forward-line 1)))
-   ((not (looking-at "^func"))
-    ;; If we are not looking at the beginning of a function line, do a regexp 
search backwards
-    (re-search-backward "\\<func\\>" nil t)
-
-    (when (not (looking-at "func"))
-      (re-search-forward "\\<func\\>" nil t)
-      (backward-word)))))
+If we are inside an anonymous function, go to that.
+If we are inside a function that has an anonymous function inside of it and we
+are below that anonymous function, go to the root function."
+  (interactive)
+  (let ((p (point)))
+    (cond
+     ((save-excursion
+        (beginning-of-line)
+        (looking-at "^//"))
+      ;; In case we are looking at the docstring, move on forward until we are
+      ;; not anymore
+      ;; TODO(thiderman): This would behave incorrectly if point is
+      ;; inside a standalone block of comments that are not a docstring.
+      (beginning-of-line)
+      (while (looking-at "^//")
+        (forward-line 1)))
+
+     ((not (looking-at "^func"))
+      ;; If we are not looking at the beginning of a function line, do a regexp
+      ;; search backwards
+      (re-search-backward "\\<func\\>" nil t)
+
+      ;; If nothing is found, assume that we are at the top of the file and
+      ;; should search forward instead.
+      (when (not (looking-at "func"))
+        (re-search-forward "\\<func\\>" nil t))
+
+      ;; If we have landed at an anonymous function, it is possible that we
+      ;; were not inside it but below it. If we were not inside it, we should
+      ;; go to the containing function.
+      (while (go--in-function-p p)
+        (go-goto-function)))))
+
+  ;; If we are still in a comment, redo the call so that we get out of it.
+  (when (go-in-comment-p)
+    (go-goto-function)))
+
+(defun go--in-function-p (compare-point)
+  "Return t if point is inside the function that starts at `compare-point', nil
+otherwise."
+  ;; Check that we are not looking at a top level function. If we are,
+  (when (not (looking-at "^func"))
+   (save-excursion
+     (go--goto-return-values)
+     ;; Try to place the point on the opening brace
+     (cond
+      ((looking-at "(")
+       (forward-list 1)
+       (forward-char 1))
+      ((not (looking-at "{"))
+       (forward-word 1)
+       (forward-char 1)))
+
+     (when (looking-at "{")
+       ;; Go past the body of the function and back inside of it.
+       (forward-list 1)
+       (backward-char 1)
+       ;; Finally, compare if our position is past the assert point.
+       ;; Return t if it is.
+       (< (point) compare-point)))))
 
 (defun go-goto-function-name ()
   "Go to the name of the current function.
@@ -1618,19 +1664,25 @@ If the function is anonymous, place point on the 'func' 
keyword."
   (forward-word 1)
   (forward-char 1))
 
+(defun go--goto-return-values ()
+  "Go to the declaration of return values for the current function."
+  (go-goto-arguments)
+  (backward-char)
+  (forward-list)
+  (forward-char))
+
 (defun go-goto-return-value ()
   "Go to the return value declaration of the current function.
 
+If there are multiple ones contained in a parenthesis, enter the parenthesis.
 If there is none, make space for one to be added."
   (interactive)
-  (go-goto-arguments)
-  (backward-char)
-  (forward-list)
-  (forward-char)
+  (go--goto-return-values)
 
   ;; Opening parenthesis, enter it
   (when (looking-at "(")
     (forward-char 1))
+
   ;; No return arguments, add space for adding
   (when (looking-at "{")
     (insert " ")

Reply via email to