Kirill Bobyrev | bbce7e2 | 2016-10-02 14:51:33 +0000 | [diff] [blame] | 1 | ;;; clang-rename.el --- Renames every occurrence of a symbol found at <offset>. -*- lexical-binding: t; -*- |
Kirill Bobyrev | aa48450 | 2016-08-02 08:51:26 +0000 | [diff] [blame] | 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 |
Kirill Bobyrev | bbce7e2 | 2016-10-02 14:51:33 +0000 | [diff] [blame] | 8 | ;; `load-path' and add |
Kirill Bobyrev | aa48450 | 2016-08-02 08:51:26 +0000 | [diff] [blame] | 9 | ;; |
| 10 | ;; (require 'clang-rename) |
| 11 | ;; |
| 12 | ;; to your .emacs configuration. |
| 13 | |
| 14 | ;;; Code: |
| 15 | |
Kirill Bobyrev | bbce7e2 | 2016-10-02 14:51:33 +0000 | [diff] [blame] | 16 | (defgroup clang-rename nil |
| 17 | "Integration with clang-rename" |
| 18 | :group 'c) |
| 19 | |
Kirill Bobyrev | aa48450 | 2016-08-02 08:51:26 +0000 | [diff] [blame] | 20 | (defcustom clang-rename-binary "clang-rename" |
| 21 | "Path to clang-rename executable." |
Kirill Bobyrev | bbce7e2 | 2016-10-02 14:51:33 +0000 | [diff] [blame] | 22 | :type '(file :must-match t) |
| 23 | :group 'clang-rename) |
Kirill Bobyrev | aa48450 | 2016-08-02 08:51:26 +0000 | [diff] [blame] | 24 | |
Kirill Bobyrev | bbce7e2 | 2016-10-02 14:51:33 +0000 | [diff] [blame] | 25 | ;;;###autoload |
Kirill Bobyrev | aa48450 | 2016-08-02 08:51:26 +0000 | [diff] [blame] | 26 | (defun clang-rename (new-name) |
Kirill Bobyrev | bbce7e2 | 2016-10-02 14:51:33 +0000 | [diff] [blame] | 27 | "Rename all instances of the symbol at point to NEW-NAME using clang-rename." |
Kirill Bobyrev | aa48450 | 2016-08-02 08:51:26 +0000 | [diff] [blame] | 28 | (interactive "sEnter a new name: ") |
Kirill Bobyrev | bbce7e2 | 2016-10-02 14:51:33 +0000 | [diff] [blame] | 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. |
Manuel Klimek | 750f6a7 | 2016-10-11 09:15:10 +0000 | [diff] [blame] | 55 | (let ((message (clang-rename--format-message |
Kirill Bobyrev | bbce7e2 | 2016-10-02 14:51:33 +0000 | [diff] [blame] | 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)))))) |
Kirill Bobyrev | aa48450 | 2016-08-02 08:51:26 +0000 | [diff] [blame] | 63 | |
Kirill Bobyrev | bbce7e2 | 2016-10-02 14:51:33 +0000 | [diff] [blame] | 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))))) |
Kirill Bobyrev | aa48450 | 2016-08-02 08:51:26 +0000 | [diff] [blame] | 71 | |
Manuel Klimek | 750f6a7 | 2016-10-11 09:15:10 +0000 | [diff] [blame] | 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 | |
Kirill Bobyrev | aa48450 | 2016-08-02 08:51:26 +0000 | [diff] [blame] | 77 | (provide 'clang-rename) |
| 78 | |
| 79 | ;;; clang-rename.el ends here |