emacs-elpa-diffs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[nongnu] elpa/go-mode 90aac96 381/495: cmd/gorename: a precise, type-awa


From: ELPA Syncer
Subject: [nongnu] elpa/go-mode 90aac96 381/495: cmd/gorename: a precise, type-aware renaming tool for Go identifiers.
Date: Sat, 7 Aug 2021 09:05:52 -0400 (EDT)

branch: elpa/go-mode
commit 90aac96330c85db17428ef909ae0530768f43bc9
Author: Alan Donovan <adonovan@google.com>
Commit: Dominik Honnef <dominik@honnef.co>

    cmd/gorename: a precise, type-aware renaming tool for Go identifiers.
    
    See the usage message in main.go for orientation.
    
    To the best of my knowledge, the tool implements all required
    soundness checks, except:
    - the dynamic behaviour of reflection is obviously undecidable.
    - it rejects method renamings that change the "implements" relation.
      It should probably be more aggressive.
    - actually it only checks the part of the "implements" relation
      needed for compilation.  Understanding the dynamic behaviour
      of interfaces is obviously undecidable.
    - a couple of minor gaps are indicated by TODO comments.
    
    Also:
    - Emacs integration.
    - tests of all safety checks and (some) successful rewrites.
    
    LGTM=dominik.honnef, sameer
    R=gri, sameer, dominik.honnef
    CC=golang-codereviews
    https://golang.org/cl/139150044
---
 rename_import/refactor/rename/rename.el | 92 +++++++++++++++++++++++++++++++++
 1 file changed, 92 insertions(+)

diff --git a/rename_import/refactor/rename/rename.el 
b/rename_import/refactor/rename/rename.el
new file mode 100644
index 0000000..c31a465
--- /dev/null
+++ b/rename_import/refactor/rename/rename.el
@@ -0,0 +1,92 @@
+;;; 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.
+;;;
+;;; Integration of the 'gorename' tool into Emacs.
+;;;
+;;; To install:
+;;; % go get code.google.com/p/go.tools/cmd/gorename
+;;; % go build code.google.com/p/go.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.
+
+(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)
+
+(defun go-rename (new-name)
+  "Rename the entity denoted by the identifier at point, using
+the `gorename' tool."
+  (interactive (list (read-string "New name: " (thing-at-point 'symbol))))
+  (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 (list go-rename-command nil t nil posflag "-to" new-name)))
+        ;; 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 (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.
+      (let ((w (display-buffer (current-buffer))))
+        (if success
+            (progn
+              (message "%s" (go--buffer-string-no-trailing-space))
+              (delete-window w))
+          ;; failure
+          (message "gorename exited")
+          (shrink-window-if-larger-than-buffer w)
+          (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))))



reply via email to

[Prev in Thread] Current Thread [Next in Thread]