@peccul is peccu

(love peccu '(emacs lisp cat outdoor bicycle mac linux coffee))

snake_case->PascalCase->camelCase->snake_case->...に変換するコマンド

id:IMAKADOさんの実装を参考に、以下を追加した。

  • リージョンだけでなくカーソルの置いているシンボル(thing-at-point)も変換対象とした
  • snake_case<->PascalCaseだけでなくcamelCaseを加えて循環するようにした

d.hatena.ne.jp

;; copied from rails-lib.el
(defun ik:decamelize (string)
  "Convert from CamelCaseString to camel_case_string."
  (let ((case-fold-search nil))
    (downcase
     (replace-regexp-in-string
      "\\([A-Z]+\\)\\([A-Z][a-z]\\)" "\\1_\\2"
      (replace-regexp-in-string
       "\\([a-z\\d]\\)\\([A-Z]\\)" "\\1_\\2"
       string)))))

(defun ik:camerize<->decamelize (str)
  (let ((case-fold-search nil))
    (cond
     ((string-match "_" str)
      (let ((los
             (mapcar 'capitalize (split-string str "_" t))))
        (mapconcat 'identity los "")))
     ((string-match "^[A-Z]" str)
      (let ((words (split-string (ik:decamelize str) "_" t)))
        (let ((los
               (append (list (car words))
                       (mapcar 'capitalize (rest words)))))
          (mapconcat 'identity los "")
          )))
     (t
      (ik:decamelize str)))))
;; (ik:camerize<->decamelize "camel_or_snake")
;; (ik:camerize<->decamelize "CamelOrSnake")
;; (ik:camerize<->decamelize "camelOrSnake")

(defun ik:camerize<->decamelize-thing-ad-point-or-region (s e)
  (interactive "r")
  (unless (use-region-p)
    (let ((bounds (bounds-of-thing-at-point 'symbol)))
      (setq s (car bounds))
      (setq e (cdr bounds))))
  (let* ((buf-str (buffer-substring-no-properties s e))
         (str (ik:camerize<->decamelize buf-str)))
    (delete-region s e)
    (insert str)))

M-c(M-x capitalize-word)やM-u (M-x upcase-word)に似て覚えやすいのでM-C (meta shift c) に割り当てて使っています。

(global-set-key (kbd "M-C") 'ik:camerize<->decamelize-thing-ad-point-or-region)