在emacs中将驼峰命名转换成下划线的方法

35

有没有一个emacs函数能够将驼峰式单词转换为下划线形式?例如:

longVariableName

M-x to-underscore

long_variable_name


2
你可能也会对 M-x glasses-mode 感兴趣,它可以在不修改底层文件的情况下,在缓冲区中神奇地插入下划线。 - Ben
7个回答

45

使用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

如果您想要以编程的方式使用它,请使用 string-inflection-underscore-function - Radon Rosborough
1
@RadonRosborough 现在是 string-inflection-underscore - UTF-8

26
我使用以下代码在驼峰式和下划线之间进行切换:

(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)))))))

22
(progn (replace-regexp "\\([A-Z]\\)" "_\\1" nil (region-beginning) (region-end))
       (downcase-region (region-beginning) (region-end)))

5
为了分配 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))) ) - Lucian Adrian Grijincu

10

我在将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-mode中fn:

(local-set-key "\M-\C-C"  'un-camelcase-word-at-point)

7

现在在2018年还有另一种通用的方法:magnars/s.el: 这是失落已久的Emacs字符串操作库。- github.com,下面是一些与OP问题相关的示例:

  1. whatever case to snake case(underscore seperated):

    (s-snake-case "some words") ;; => "some_words"
    (s-snake-case "dashed-words") ;; => "dashed_words"
    (s-snake-case "camelCasedWords") ;; => "camel_cased_words"
    
  2. whatever case to lower camel case:

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

请到该仓库查看更多示例。


当我们处于缓冲区时,如何在某个区域中使用它? 我尝试了M-x s-lower-camel-case,但似乎并没有起作用。 - ancora imparo
@ancoraimparo 这不是一个命令,所以你可以直接在 M-x ... 中使用它。 - whatacold

1

如果您想使用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")))

0

@ens的回答接近了,但在Emacs 26.1上对我来说有点小问题。我修复了这个bug,并通过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)))))))

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接