1*e5dd7070Spatrick;;; clang-rename.el --- Renames every occurrence of a symbol found at <offset>. -*- lexical-binding: t; -*- 2*e5dd7070Spatrick 3*e5dd7070Spatrick;; Keywords: tools, c 4*e5dd7070Spatrick 5*e5dd7070Spatrick;;; Commentary: 6*e5dd7070Spatrick 7*e5dd7070Spatrick;; To install clang-rename.el make sure the directory of this file is in your 8*e5dd7070Spatrick;; `load-path' and add 9*e5dd7070Spatrick;; 10*e5dd7070Spatrick;; (require 'clang-rename) 11*e5dd7070Spatrick;; 12*e5dd7070Spatrick;; to your .emacs configuration. 13*e5dd7070Spatrick 14*e5dd7070Spatrick;;; Code: 15*e5dd7070Spatrick 16*e5dd7070Spatrick(defgroup clang-rename nil 17*e5dd7070Spatrick "Integration with clang-rename" 18*e5dd7070Spatrick :group 'c) 19*e5dd7070Spatrick 20*e5dd7070Spatrick(defcustom clang-rename-binary "clang-rename" 21*e5dd7070Spatrick "Path to clang-rename executable." 22*e5dd7070Spatrick :type '(file :must-match t) 23*e5dd7070Spatrick :group 'clang-rename) 24*e5dd7070Spatrick 25*e5dd7070Spatrick;;;###autoload 26*e5dd7070Spatrick(defun clang-rename (new-name) 27*e5dd7070Spatrick "Rename all instances of the symbol at point to NEW-NAME using clang-rename." 28*e5dd7070Spatrick (interactive "sEnter a new name: ") 29*e5dd7070Spatrick (save-some-buffers :all) 30*e5dd7070Spatrick ;; clang-rename should not be combined with other operations when undoing. 31*e5dd7070Spatrick (undo-boundary) 32*e5dd7070Spatrick (let ((output-buffer (get-buffer-create "*clang-rename*"))) 33*e5dd7070Spatrick (with-current-buffer output-buffer (erase-buffer)) 34*e5dd7070Spatrick (let ((exit-code (call-process 35*e5dd7070Spatrick clang-rename-binary nil output-buffer nil 36*e5dd7070Spatrick (format "-offset=%d" 37*e5dd7070Spatrick ;; clang-rename wants file (byte) offsets, not 38*e5dd7070Spatrick ;; buffer (character) positions. 39*e5dd7070Spatrick (clang-rename--bufferpos-to-filepos 40*e5dd7070Spatrick ;; Emacs treats one character after a symbol as 41*e5dd7070Spatrick ;; part of the symbol, but clang-rename doesn’t. 42*e5dd7070Spatrick ;; Use the beginning of the current symbol, if 43*e5dd7070Spatrick ;; available, to resolve the inconsistency. 44*e5dd7070Spatrick (or (car (bounds-of-thing-at-point 'symbol)) 45*e5dd7070Spatrick (point)) 46*e5dd7070Spatrick 'exact)) 47*e5dd7070Spatrick (format "-new-name=%s" new-name) 48*e5dd7070Spatrick "-i" (buffer-file-name)))) 49*e5dd7070Spatrick (if (and (integerp exit-code) (zerop exit-code)) 50*e5dd7070Spatrick ;; Success; revert current buffer so it gets the modifications. 51*e5dd7070Spatrick (progn 52*e5dd7070Spatrick (kill-buffer output-buffer) 53*e5dd7070Spatrick (revert-buffer :ignore-auto :noconfirm :preserve-modes)) 54*e5dd7070Spatrick ;; Failure; append exit code to output buffer and display it. 55*e5dd7070Spatrick (let ((message (clang-rename--format-message 56*e5dd7070Spatrick "clang-rename failed with %s %s" 57*e5dd7070Spatrick (if (integerp exit-code) "exit status" "signal") 58*e5dd7070Spatrick exit-code))) 59*e5dd7070Spatrick (with-current-buffer output-buffer 60*e5dd7070Spatrick (insert ?\n message ?\n)) 61*e5dd7070Spatrick (message "%s" message) 62*e5dd7070Spatrick (display-buffer output-buffer)))))) 63*e5dd7070Spatrick 64*e5dd7070Spatrick(defalias 'clang-rename--bufferpos-to-filepos 65*e5dd7070Spatrick (if (fboundp 'bufferpos-to-filepos) 66*e5dd7070Spatrick 'bufferpos-to-filepos 67*e5dd7070Spatrick ;; Emacs 24 doesn’t have ‘bufferpos-to-filepos’, simulate it using 68*e5dd7070Spatrick ;; ‘position-bytes’. 69*e5dd7070Spatrick (lambda (position &optional _quality _coding-system) 70*e5dd7070Spatrick (1- (position-bytes position))))) 71*e5dd7070Spatrick 72*e5dd7070Spatrick;; ‘format-message’ is new in Emacs 25.1. Provide a fallback for older 73*e5dd7070Spatrick;; versions. 74*e5dd7070Spatrick(defalias 'clang-rename--format-message 75*e5dd7070Spatrick (if (fboundp 'format-message) 'format-message 'format)) 76*e5dd7070Spatrick 77*e5dd7070Spatrick(provide 'clang-rename) 78*e5dd7070Spatrick 79*e5dd7070Spatrick;;; clang-rename.el ends here 80