vim macro to convert CamelCase to lowercase_with_underscores

Is there a vim macro to convert CamelCase to lowercase_with_underscores and vice versa?


Solution 1:

Tim Pope’s abolish.vim can convert among camelCase, MixedCase (also known as PascalCase), snake_case, and UPPER_CASE, as well as convert (one-way) to dash-case.

Position the cursor on any of fooBar, FooBar, foo_bar, or FOO_BAR and use

  • crc to convert to fooBar
  • crm to convert to FooBar
  • cr_ or
    crs to convert to foo_bar
  • cru to convert to FOO_BAR
  • cr- to convert to foo-bar

Solution 2:

Yes there is, and as a bonus there's one there to go the opposite direction as well!

Quote from the wiki in case it goes away:

" Change selected text from NameLikeThis to name_like_this.
vnoremap ,u :s/\<\@!\([A-Z]\)/\_\l\1/g<CR>gul

and for the opposite direction:

" Change selected text from name_like_this to NameLikeThis.
vnoremap ,c :s/_\([a-z]\)/\u\1/g<CR>gUl

Solution 3:

lh-dev also provides commands to convert between naming styles:

:NameConvert snake

will convert the word under the cursor to snake_case.

:%ConvertNames/\<m_\k\+(/getter/gc

will convert each occurrence of the pattern to a getter name, assuming the user confirms the transformation (:h :s_flags)

The styles supported are of two kinds:

  • exact styles (snake_case, UpperCamelCase, lowerCamelCase)
  • semantic styles (local, global, member, parameter, getter, setter, constant, static, function, type, ...) which can be tuned to fit current project naming conventions.

Solution 4:

I created a command like this:

command! Ctl
    \ exec "norm \"xygn" |
    \ let @y = substitute(@x, "\\([^A-Z]\\)\\([A-Z]\\)", "\\1_\\2", "g") |
    \ let @y = tolower(@y) |
    \ exec "norm cgn\<C-r>y" |
    \ let @@ = ":Ctl\n"

You first must search for a string you want to replace /nameToReplace and then you run :Ctl, and the next search match will become name_to_replace. The command puts itself into the @@ register so you can repeat the action by pressing @@.