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