Преобразование из camelcase в _ в emacs

Есть ли функция emacs для преобразования слова в верблюжьем регистре в подчеркивание? Что-то типа:

longVariableName

M-x to-underscore

long_variable_name


person David Nehme    schedule 15.02.2012    source источник
comment
Вас также может заинтересовать M-x glasses-mode, который волшебным образом вставляет символы подчеркивания в буфер, не изменяя базовый файл.   -  person Ben    schedule 16.02.2012
comment
@tripleee. Оказывается, это теперь является самым популярным в Google. И на этой странице emacswiki есть куча мусора, одним из которых является функция, но в общем случае эта функция на самом деле не работает. Ответ здесь лучше. В любом случае, ругать людей за то, что они задают вопросы на сайте вопросов и ответов, действительно кажется излишним.   -  person Cheeso    schedule 06.03.2013


Ответы (7)


Используйте пакет string-inflection, доступный на MELPA, или по адресу https://github.com/akicho8/string-inflection.

Полезные сочетания клавиш, скопированные с https://www.emacswiki.org/emacs/CamelCase:

;; Cycle between snake case, camel case, etc.
(require 'string-inflection)
(global-set-key (kbd "C-c i") 'string-inflection-cycle)
(global-set-key (kbd "C-c C") 'string-inflection-camelcase)        ;; Force to CamelCase
(global-set-key (kbd "C-c L") 'string-inflection-lower-camelcase)  ;; Force to lowerCamelCase
(global-set-key (kbd "C-c J") 'string-inflection-java-style-cycle) ;; Cycle through Java styles
person Nik    schedule 11.12.2014
comment
Если вы хотите использовать это программно, используйте string-inflection-underscore-function. - person Radon Rosborough; 16.08.2017
comment
@RadonRosborough сейчас string-inflection-underscore. - person UTF-8; 25.11.2020

Я использую следующее для переключения между верблюжьим регистром и подчеркиванием:

(defun toggle-camelcase-underscores ()
  "Toggle between camelcase and underscore notation for the symbol at point."
  (interactive)
  (save-excursion
    (let* ((bounds (bounds-of-thing-at-point 'symbol))
           (start (car bounds))
           (end (cdr bounds))
           (currently-using-underscores-p (progn (goto-char start)
                                                 (re-search-forward "_" end t))))
      (if currently-using-underscores-p
          (progn
            (upcase-initials-region start end)
            (replace-string "_" "" nil start end)
            (downcase-region start (1+ start)))
        (replace-regexp "\\([A-Z]\\)" "_\\1" nil (1+ start) end)
        (downcase-region start (cdr (bounds-of-thing-at-point 'symbol)))))))
person ens    schedule 17.09.2014

Я использую это при преобразовании кода C# в PHP.

(defun un-camelcase-word-at-point ()
  "un-camelcase the word at point, replacing uppercase chars with
the lowercase version preceded by an underscore.

The first char, if capitalized (eg, PascalCase) is just
downcased, no preceding underscore.
"
  (interactive)
  (save-excursion
    (let ((bounds (bounds-of-thing-at-point 'word)))
      (replace-regexp "\\([A-Z]\\)" "_\\1" nil
                      (1+ (car bounds)) (cdr bounds))
      (downcase-region (car bounds) (cdr bounds)))))

И затем в моем php-режиме fn:

(local-set-key "\M-\C-C"  'un-camelcase-word-at-point)
person Cheeso    schedule 06.03.2013
comment
Прохладный! Давай что я хочу. - person linjunhalida; 08.02.2017

В 2018 году появился еще один общий способ: magnars/s.el: давно потерянная библиотека Emacs для работы со строками. - github.com, несколько примеров по вопросу ОП:

  1. любой случай для змеиного случая (подчеркивание отдельно):

    (s-snake-case "some words") ;; => "some_words"
    (s-snake-case "dashed-words") ;; => "dashed_words"
    (s-snake-case "camelCasedWords") ;; => "camel_cased_words"
    
  2. в любом случае для нижнего регистра верблюда:

    (s-lower-camel-case "some words") ;; => "someWords"
    (s-lower-camel-case "dashed-words") ;; => "dashedWords"
    (s-lower-camel-case "under_scored_words") ;; => "underScoredWords"
    

см. больше примеров в его репо.

person whatacold    schedule 30.08.2018

Ответ @ens был близок, но для меня немного глючил на Emacs 26.1. Я исправил ошибку и добавил возможность с помощью аргумента префикса C-u указать, хотите ли вы, чтобы первая буква верблюжьего регистра была строчной:

(defun toggle-camelcase-underscores (first-lower-p)
  "Toggle between camelcase and underscore notation for the
symbol at point. If prefix arg, C-u, is supplied, then make first
letter of camelcase lowercase."
  (interactive "P")
  (save-excursion
    (let* ((bounds (bounds-of-thing-at-point 'symbol))
           (start (car bounds))
           (end (cdr bounds))
           (currently-using-underscores-p (progn (goto-char start)
                                                 (re-search-forward "_" end t))))
      (if currently-using-underscores-p
          (progn
            (replace-string "_" " " nil start end)
            (upcase-initials-region start end)
            (replace-string " " "" nil start end)
            (when first-lower-p
              (downcase-region start (1+ start))))
        (replace-regexp "\\([A-Z]\\)" "_\\1" nil (1+ start) end)
        (downcase-region start (cdr (bounds-of-thing-at-point 'symbol)))))))
person Joe    schedule 07.10.2019

Если вы хотите получить полный код, используя s.el:

(defun to-snake-case (start end)
  "Change selected text to snake case format"
  (interactive "r")
  (if (use-region-p)
      (let ((camel-case-str (buffer-substring start end)))
        (delete-region start end)
        (insert (s-snake-case camel-case-str)))
    (message "No region selected")))
person azzamsa    schedule 12.05.2020

person    schedule
comment
Чтобы назначить to-underscore (чтобы вы могли сделать M-x to-underscore): (defun to-underscore () (interactive) (progn (replace-regexp "\\([A-Z]\\)" "_\\1" nil (region-beginning) (region-end)) (downcase-region (region-beginning) (region-end))) ) - person Lucian Adrian Grijincu; 30.03.2017