|
|
;;; clang-rename.el --- Renames every occurrence of a symbol found at <offset>. -*- lexical-binding: t; -*-
|
|
|
|
|
|
;; Keywords: tools, c
|
|
|
|
|
|
;;; Commentary:
|
|
|
|
|
|
;; To install clang-rename.el make sure the directory of this file is in your
|
|
|
;; `load-path' and add
|
|
|
;;
|
|
|
;; (require 'clang-rename)
|
|
|
;;
|
|
|
;; to your .emacs configuration.
|
|
|
|
|
|
;;; Code:
|
|
|
|
|
|
(defgroup clang-rename nil
|
|
|
"Integration with clang-rename"
|
|
|
:group 'c)
|
|
|
|
|
|
(defcustom clang-rename-binary "clang-rename"
|
|
|
"Path to clang-rename executable."
|
|
|
:type '(file :must-match t)
|
|
|
:group 'clang-rename)
|
|
|
|
|
|
;;;###autoload
|
|
|
(defun clang-rename (new-name)
|
|
|
"Rename all instances of the symbol at point to NEW-NAME using clang-rename."
|
|
|
(interactive "sEnter a new name: ")
|
|
|
(save-some-buffers :all)
|
|
|
;; clang-rename should not be combined with other operations when undoing.
|
|
|
(undo-boundary)
|
|
|
(let ((output-buffer (get-buffer-create "*clang-rename*")))
|
|
|
(with-current-buffer output-buffer (erase-buffer))
|
|
|
(let ((exit-code (call-process
|
|
|
clang-rename-binary nil output-buffer nil
|
|
|
(format "-offset=%d"
|
|
|
;; clang-rename wants file (byte) offsets, not
|
|
|
;; buffer (character) positions.
|
|
|
(clang-rename--bufferpos-to-filepos
|
|
|
;; Emacs treats one character after a symbol as
|
|
|
;; part of the symbol, but clang-rename doesn’t.
|
|
|
;; Use the beginning of the current symbol, if
|
|
|
;; available, to resolve the inconsistency.
|
|
|
(or (car (bounds-of-thing-at-point 'symbol))
|
|
|
(point))
|
|
|
'exact))
|
|
|
(format "-new-name=%s" new-name)
|
|
|
"-i" (buffer-file-name))))
|
|
|
(if (and (integerp exit-code) (zerop exit-code))
|
|
|
;; Success; revert current buffer so it gets the modifications.
|
|
|
(progn
|
|
|
(kill-buffer output-buffer)
|
|
|
(revert-buffer :ignore-auto :noconfirm :preserve-modes))
|
|
|
;; Failure; append exit code to output buffer and display it.
|
|
|
(let ((message (clang-rename--format-message
|
|
|
"clang-rename failed with %s %s"
|
|
|
(if (integerp exit-code) "exit status" "signal")
|
|
|
exit-code)))
|
|
|
(with-current-buffer output-buffer
|
|
|
(insert ?\n message ?\n))
|
|
|
(message "%s" message)
|
|
|
(display-buffer output-buffer))))))
|
|
|
|
|
|
(defalias 'clang-rename--bufferpos-to-filepos
|
|
|
(if (fboundp 'bufferpos-to-filepos)
|
|
|
'bufferpos-to-filepos
|
|
|
;; Emacs 24 doesn’t have ‘bufferpos-to-filepos’, simulate it using
|
|
|
;; ‘position-bytes’.
|
|
|
(lambda (position &optional _quality _coding-system)
|
|
|
(1- (position-bytes position)))))
|
|
|
|
|
|
;; ‘format-message’ is new in Emacs 25.1. Provide a fallback for older
|
|
|
;; versions.
|
|
|
(defalias 'clang-rename--format-message
|
|
|
(if (fboundp 'format-message) 'format-message 'format))
|
|
|
|
|
|
(provide 'clang-rename)
|
|
|
|
|
|
;;; clang-rename.el ends here
|