[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[nongnu] elpa/go-mode aa9a40c 351/495: cmd/guru: in Emacs, change 'defin
From: |
ELPA Syncer |
Subject: |
[nongnu] elpa/go-mode aa9a40c 351/495: cmd/guru: in Emacs, change 'definition' to jump directly |
Date: |
Sat, 7 Aug 2021 09:05:46 -0400 (EDT) |
branch: elpa/go-mode
commit aa9a40cc9f2be8dd8d2886e9c79ecf9676364a81
Author: Alan Donovan <alan@alandonovan.net>
Commit: Dominik Honnef <dominik@honnef.co>
cmd/guru: in Emacs, change 'definition' to jump directly
go-guru--run has been split up to separate running the tool
from turning its output into compilation-mode form.
The definition command uses only the first part,
and parses its output in JSON form.
Added test, factoring the test script.
Change-Id: I4c3e4a51a1346551a3703a5e3137c878d7b2d95f
Reviewed-on: https://go-review.googlesource.com/19499
Reviewed-by: Michael Matloob <matloob@golang.org>
---
guru_import/cmd/guru/guru.el | 129 ++++++++++++++++++++++++++-----------------
1 file changed, 78 insertions(+), 51 deletions(-)
diff --git a/guru_import/cmd/guru/guru.el b/guru_import/cmd/guru/guru.el
index e9fed47..137d35e 100644
--- a/guru_import/cmd/guru/guru.el
+++ b/guru_import/cmd/guru/guru.el
@@ -11,6 +11,7 @@
(require 'compile)
(require 'go-mode)
+(require 'json)
(require 'simple)
(require 'cl)
@@ -61,10 +62,10 @@ previous scope.
The scope specifies a set of arguments, separated by spaces.
It may be:
-1) a set of packages whose main() functions will be analyzed.
+1) a set of packages whose main functions will be analyzed.
2) a list of *.go filenames; they will treated like as a single
package (see #3).
-3) a single package whose main() function and/or Test* functions
+3) a single package whose main function and/or Test* functions
will be analyzed.
In the common case, this is similar to the argument(s) you would
@@ -80,10 +81,18 @@ specify to 'go build'."
(setq go-guru-scope scope)))
(defun go-guru--run (mode &optional need-scope)
- "Run the Go guru in the specified MODE, passing it the
+ "Run the Go guru in the specified MODE, passing it the selected
+region of the current buffer. If NEED-SCOPE, prompt for a scope
+if not already set. Mark up the output using `compilation-node`,
+replacing each file name with a small hyperlink, and display the
+result."
+ (with-current-buffer (go-guru--exec mode need-scope)
+ (go-guru--compilation-markup)))
+
+(defun go-guru--exec (mode &optional need-scope flags)
+ "Execute the Go guru in the specified MODE, passing it the
selected region of the current buffer. If NEED-SCOPE, prompt for
-a scope if not already set. Process the output to replace each
-file name with a small hyperlink. Display the result."
+a scope if not already set. Return the output buffer."
(if (not buffer-file-name)
(error "Cannot use guru on a buffer without a file name"))
(and need-scope
@@ -104,16 +113,15 @@ file name with a small hyperlink. Display the result."
(output-buffer (get-buffer-create "*go-guru*")))
(with-current-buffer output-buffer
(setq buffer-read-only nil)
- (erase-buffer)
- (insert "Go Guru\n"))
+ (erase-buffer))
(with-current-buffer (get-buffer-create "*go-guru-input*")
(setq buffer-read-only nil)
(erase-buffer)
(go-guru--insert-modified-files)
- (let* ((args (list "-modified"
- "-scope" go-guru-scope
- mode
- posn)))
+ (let* ((args (append (list "-modified"
+ "-scope" go-guru-scope)
+ flags
+ (list mode posn))))
;; Log the command to *Messages*, for debugging.
(message "Command: %s:" args)
(message nil) ; clears/shrinks minibuffer
@@ -127,44 +135,46 @@ file name with a small hyperlink. Display the result."
output-buffer
t)
args)))))
- (with-current-buffer output-buffer
- (insert "\n")
- (compilation-mode)
- (setq compilation-error-screen-columns nil)
-
- ;; Hide the file/line info to save space.
- ;; Replace each with a little widget.
- ;; compilation-mode + this loop = slooow.
- ;; TODO(adonovan): have guru give us JSON
- ;; and we'll do the markup directly.
- (let ((buffer-read-only nil)
- (p 1))
- (while (not (null p))
- (let ((np (compilation-next-single-property-change p
'compilation-message)))
- (if np
- (when (equal (line-number-at-pos p) (line-number-at-pos np))
- ;; Using a fixed width greatly improves readability, so
- ;; if the filename is longer than 20, show
".../last/17chars.go".
- ;; This usually includes the last segment of the package
name.
- ;; Don't show the line or column number.
- (let* ((loc (buffer-substring p np)) ;
"/home/foo/go/pkg/file.go:1:2-3:4"
- (i (search ":" loc)))
- (setq loc (cond
- ((null i) "...")
- ((>= i 17) (concat "..." (substring loc (- i
17) i)))
- (t (substring loc 0 i))))
- ;; np is (typically) the space following ":"; consume it
too.
- (put-text-property p np 'display (concat loc ":")))
- (goto-char np)
- (insert " ")
- (incf np))) ; so we don't get stuck (e.g. on a panic stack
dump)
- (setq p np)))
- (message nil))
-
- (let ((w (display-buffer (current-buffer))))
- (balance-windows)
- (shrink-window-if-larger-than-buffer w)
- (set-window-point w (point-min))))))
+ output-buffer))
+
+(defun go-guru--compilation-markup ()
+ "Present guru output in the current buffer using `compilation-mode'."
+ (insert "\n")
+ (compilation-mode)
+ (setq compilation-error-screen-columns nil)
+
+ ;; Hide the file/line info to save space.
+ ;; Replace each with a little widget.
+ ;; compilation-mode + this loop = slooow.
+ ;; TODO(adonovan): have guru give us JSON
+ ;; and we'll do the markup directly.
+ (let ((buffer-read-only nil)
+ (p 1))
+ (while (not (null p))
+ (let ((np (compilation-next-single-property-change p
'compilation-message)))
+ (if np
+ (when (equal (line-number-at-pos p) (line-number-at-pos np))
+ ;; Using a fixed width greatly improves readability, so
+ ;; if the filename is longer than 20, show ".../last/17chars.go".
+ ;; This usually includes the last segment of the package name.
+ ;; Don't show the line or column number.
+ (let* ((loc (buffer-substring p np)) ;
"/home/foo/go/pkg/file.go:1:2-3:4"
+ (i (search ":" loc)))
+ (setq loc (cond
+ ((null i) "...")
+ ((>= i 17) (concat "..." (substring loc (- i 17) i)))
+ (t (substring loc 0 i))))
+ ;; np is (typically) the space following ":"; consume it too.
+ (put-text-property p np 'display (concat loc ":")))
+ (goto-char np)
+ (insert " ")
+ (incf np))) ; so we don't get stuck (e.g. on a panic stack dump)
+ (setq p np)))
+ (message nil))
+
+ (let ((w (display-buffer (current-buffer))))
+ (shrink-window-if-larger-than-buffer w)
+ (set-window-point w (point-min))))
(defun go-guru--insert-modified-files ()
"Insert the contents of each modified Go buffer into the
@@ -180,6 +190,16 @@ current buffer in the format specified by guru's -modified
flag."
(insert-buffer-substring b))))
(buffer-list)))
+(defun go-guru--goto-pos (posn)
+ "Find the file containing the position POSN (of the form `file:line:col')
+set the point to it, switching the current buffer."
+ (let ((file-line-pos (split-string posn ":")))
+ (find-file (car file-line-pos))
+ (goto-char (point-min))
+ ;; NB: go/token's column offsets are byte- not rune-based.
+ (forward-line (1- (string-to-number (cadr file-line-pos))))
+ (forward-char (1- (string-to-number (caddr file-line-pos))))))
+
(defun go-guru-callees ()
"Show possible callees of the function call at the current point."
(interactive)
@@ -202,9 +222,16 @@ function containing the current point."
(go-guru--run "callstack" t))
(defun go-guru-definition ()
- "Show the definition of the selected identifier."
+ "Jump to the definition of the selected identifier."
(interactive)
- (go-guru--run "definition"))
+ ;; TODO(adonovan): use -format=sexpr when available to avoid a
+ ;; dependency and to simplify parsing.
+ (let* ((res (with-current-buffer (go-guru--exec "definition" nil
'("-format=json"))
+ (goto-char (point-min))
+ (cdr (car (json-read)))))
+ (desc (cdr (assoc 'desc res))))
+ (go-guru--goto-pos (cdr (assoc 'objpos res)))
+ (message "%s" desc)))
(defun go-guru-describe ()
"Describe the selected syntax, its kind, type and methods."
- [nongnu] elpa/go-mode 22cbf11 321/495: Support unsaved buffers with gogetdoc, (continued)
- [nongnu] elpa/go-mode 22cbf11 321/495: Support unsaved buffers with gogetdoc, ELPA Syncer, 2021/08/07
- [nongnu] elpa/go-mode 0b25cb5 327/495: Generate HTTPS URL for playground entry, ELPA Syncer, 2021/08/07
- [nongnu] elpa/go-mode f63d982 323/495: Make godoc interactive again, ELPA Syncer, 2021/08/07
- [nongnu] elpa/go-mode 218d8c5 346/495: cmd/oracle: emacs: look for oracle on $PATH and nowhere else, ELPA Syncer, 2021/08/07
- [nongnu] elpa/go-mode aa733d8 339/495: go.tools/oracle: turn emacs integration into minor-mode, ELPA Syncer, 2021/08/07
- [nongnu] elpa/go-mode cbf7274 343/495: x/tools/oracle: add whicherrs query mode, ELPA Syncer, 2021/08/07
- [nongnu] elpa/go-mode 01dff21 358/495: cmd/guru: emacs: package.el compatibility changes, ELPA Syncer, 2021/08/07
- [nongnu] elpa/go-mode dc424ef 361/495: cmd/guru: emacs: add default key binding for whicherrs, ELPA Syncer, 2021/08/07
- [nongnu] elpa/go-mode 6bfbd41 371/495: cmd/guru: emacs: report most specific element in expand-region, ELPA Syncer, 2021/08/07
- [nongnu] elpa/go-mode 9753f6a 342/495: go.tools: use golang.org/x/... import paths, ELPA Syncer, 2021/08/07
- [nongnu] elpa/go-mode aa9a40c 351/495: cmd/guru: in Emacs, change 'definition' to jump directly,
ELPA Syncer <=
- [nongnu] elpa/go-mode 95e7a6f 377/495: cmd/guru: emacs: Use cl-lib.el instead of cl.el, ELPA Syncer, 2021/08/07
- [nongnu] elpa/go-mode 2e9ec69 376/495: cmd/guru: update Emacs installation documentation, ELPA Syncer, 2021/08/07
- [nongnu] elpa/go-mode 37f595f 365/495: cmd/guru: emacs: support running on nameless buffers, ELPA Syncer, 2021/08/07
- [nongnu] elpa/go-mode 9d5f10a 366/495: cmd/guru: emacs: store output in separate buffer, ELPA Syncer, 2021/08/07
- [nongnu] elpa/go-mode 6a92c3b 349/495: cmd/guru: clean ups to command-line interface, ELPA Syncer, 2021/08/07
- [nongnu] elpa/go-mode b2837e7 345/495: cmd/oracle: expect oracle binary beneath $GOBIN, $GOPATH/bin, or $GOROOT/bin, ELPA Syncer, 2021/08/07
- [nongnu] elpa/go-mode f1b8ed0 337/495: go.tools/cmd/oracle: use -pos=file:#start, #end syntax to indicate half-open [start, end) extent of byte offsets., ELPA Syncer, 2021/08/07
- [nongnu] elpa/go-mode 7580ac3 359/495: cmd/guru: emacs: allow passing tags to guru, ELPA Syncer, 2021/08/07
- [nongnu] elpa/go-mode 90aac96 381/495: cmd/gorename: a precise, type-aware renaming tool for Go identifiers., ELPA Syncer, 2021/08/07
- [nongnu] elpa/go-mode 34e7efe 356/495: cmd/guru: emacs: do not shrink results window, ELPA Syncer, 2021/08/07