| ;;; 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 |