branch: elpa/go-mode
commit 8144ae8bcadf2af59d8073e44ee46142beefcace
Merge: 04a2946 12ef34c
Author: Dominik Honnef <[email protected]>
Commit: Dominik Honnef <[email protected]>
Merge commit '12ef34c'
---
AUTHORS | 1 +
go-rename.el | 108 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 109 insertions(+)
diff --git a/AUTHORS b/AUTHORS
index c8e74d2..516a29e 100644
--- a/AUTHORS
+++ b/AUTHORS
@@ -19,6 +19,7 @@ Iwasaki Yudai <[email protected]>
James Aguilar <[email protected]>
Jan Newmarch <[email protected]>
Jean-Marc Eurin <[email protected]>
+Jeff Hodges <[email protected]>
Juergen Hoetzel <[email protected]>
Kevin Ballard <[email protected]>
Konstantin Shaposhnikov <[email protected]>
diff --git a/go-rename.el b/go-rename.el
new file mode 100644
index 0000000..f12d363
--- /dev/null
+++ b/go-rename.el
@@ -0,0 +1,108 @@
+;;; go-rename.el --- Integration of the 'gorename' tool into Emacs.
+
+;; Copyright 2014 The Go Authors. All rights reserved.
+;; Use of this source code is governed by a BSD-style
+;; license that can be found in the LICENSE file.
+
+;; Version: 0.1
+;; Package-Requires: ((go-mode "1.3.1"))
+;; Keywords: tools
+
+;;; Commentary:
+
+;; To install:
+
+;; % go get golang.org/x/tools/cmd/gorename
+;; % go build golang.org/x/tools/cmd/gorename
+;; % mv gorename $HOME/bin/ # or elsewhere on $PATH
+
+;; The go-rename-command variable can be customized to specify an
+;; alternative location for the installed command.
+
+;;; Code:
+
+(require 'cl-lib)
+(require 'compile)
+(require 'go-mode)
+(require 'thingatpt)
+
+(defgroup go-rename nil
+ "Options specific to the Go rename."
+ :group 'go)
+
+(defcustom go-rename-command "gorename"
+ "The `gorename' command; by the default, $PATH is searched."
+ :type 'string
+ :group 'go-rename)
+
+;;;###autoload
+(defun go-rename (new-name &optional force)
+ "Rename the entity denoted by the identifier at point, using
+the `gorename' tool. With FORCE, call `gorename' with the
+`-force' flag."
+ (interactive (list (read-string "New name: " (thing-at-point 'symbol))
+ current-prefix-arg))
+ (if (not buffer-file-name)
+ (error "Cannot use go-rename on a buffer without a file name"))
+ ;; It's not sufficient to save the current buffer if modified,
+ ;; since if gofmt-before-save is on the before-save-hook,
+ ;; saving will disturb the selected region.
+ (if (buffer-modified-p)
+ (error "Please save the current buffer before invoking go-rename"))
+ ;; Prompt-save all other modified Go buffers, since they might get written.
+ (save-some-buffers nil #'(lambda ()
+ (and (buffer-file-name)
+ (string= (file-name-extension (buffer-file-name)) ".go"))))
+ (let* ((posflag (format "-offset=%s:#%d"
+ buffer-file-name
+ (1- (go--position-bytes (point)))))
+ (env-vars (go-root-and-paths))
+ (goroot-env (concat "GOROOT=" (car env-vars)))
+ (gopath-env (concat "GOPATH=" (mapconcat #'identity (cdr env-vars)
":")))
+ success)
+ (with-current-buffer (get-buffer-create "*go-rename*")
+ (setq buffer-read-only nil)
+ (erase-buffer)
+ (let ((args (append (list go-rename-command nil t nil posflag "-to"
new-name) (if force '("-force")))))
+ ;; Log the command to *Messages*, for debugging.
+ (message "Command: %s:" args)
+ (message "Running gorename...")
+ ;; Use dynamic binding to modify/restore the environment
+ (setq success (zerop (let ((process-environment (cl-list* goroot-env
gopath-env process-environment)))
+ (apply #'call-process args))))
+ (insert "\n")
+ (compilation-mode)
+ (setq compilation-error-screen-columns nil)
+
+ ;; On success, print the one-line result in the message bar,
+ ;; and hide the *go-rename* buffer.
+ (if success
+ (progn
+ (message "%s" (go--buffer-string-no-trailing-space))
+ (gofmt--kill-error-buffer (current-buffer)))
+ ;; failure
+ (let ((w (display-buffer (current-buffer))))
+ (message "gorename exited")
+ (set-window-point w (point-min)))))))
+
+ ;; Reload the modified files, saving line/col.
+ ;; (Don't restore the point since the text has changed.)
+ ;;
+ ;; TODO(adonovan): should we also do this for all other files
+ ;; that were updated (the tool can print them)?
+ (let ((line (line-number-at-pos))
+ (col (current-column)))
+ (revert-buffer t t t) ; safe, because we just saved it
+ (goto-char (point-min))
+ (forward-line (1- line))
+ (forward-char col)))
+
+
+(defun go--buffer-string-no-trailing-space ()
+ (replace-regexp-in-string "[\t\n ]*\\'"
+ ""
+ (buffer-substring (point-min) (point-max))))
+
+(provide 'go-rename)
+
+;;; go-rename.el ends here