emacs: add a "godoc" command, like M-x man
This runs godoc and displays its output in a new buffer.
R=golang-dev, rsc
CC=golang-dev
https://golang.org/cl/5268041
diff --git a/misc/emacs/go-mode.el b/misc/emacs/go-mode.el
index 271677b..e099214 100644
--- a/misc/emacs/go-mode.el
+++ b/misc/emacs/go-mode.el
@@ -541,4 +541,49 @@
(interactive)
(when (eq major-mode 'go-mode) (gofmt)))
+
+(defun godoc-read-query ()
+ "Read a godoc query from the minibuffer."
+ ;; Compute the default query as the symbol under the cursor.
+ ;; TODO: This does the wrong thing for e.g. multipart.NewReader (it only grabs
+ ;; half) but I see no way to disambiguate that from e.g. foobar.SomeMethod.
+ (let* ((bounds (bounds-of-thing-at-point 'symbol))
+ (symbol (if bounds
+ (buffer-substring-no-properties (car bounds)
+ (cdr bounds)))))
+ (read-string (if symbol
+ (format "godoc (default %s): " symbol)
+ "godoc: ")
+ nil nil symbol)))
+
+(defun godoc-get-buffer (query)
+ "Get an empty buffer for a godoc query."
+ (let* ((buffer-name (concat "*godoc " query "*"))
+ (buffer (get-buffer buffer-name)))
+ ;; Kill the existing buffer if it already exists.
+ (when buffer (kill-buffer buffer))
+ (get-buffer-create buffer-name)))
+
+(defun godoc-buffer-sentinel (proc event)
+ "Sentinel function run when godoc command completes."
+ (with-current-buffer (process-buffer proc)
+ (cond ((string= event "finished\n") ;; Successful exit.
+ (goto-char (point-min))
+ (display-buffer (current-buffer) 'not-this-window))
+ ((not (= (process-exit-status proc) 0)) ;; Error exit.
+ (let ((output (buffer-string)))
+ (kill-buffer (current-buffer))
+ (message (concat "godoc: " output)))))))
+
+;;;###autoload
+(defun godoc (query)
+ "Show go documentation for a query, much like M-x man."
+ (interactive (list (godoc-read-query)))
+ (unless (string= query "")
+ (set-process-sentinel
+ (start-process-shell-command "godoc" (godoc-get-buffer query)
+ (concat "godoc " query))
+ 'godoc-buffer-sentinel)
+ nil))
+
(provide 'go-mode)