80 lines
		
	
	
		
			3.1 KiB
		
	
	
	
		
			EmacsLisp
		
	
	
	
			
		
		
	
	
			80 lines
		
	
	
		
			3.1 KiB
		
	
	
	
		
			EmacsLisp
		
	
	
	
;;; 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
 |