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