Vim Tips Wiki
Advertisement
Tip 1602 Printable Monobook Previous Next

created 2008 · complexity basic · version 7.0


The coding style for one project may use CamelCase for variables, while another may use under_scores. Here are some Vim procedures to switch between CamelCase and under_score variable names.

Converting from legacy PHP

This is a simple procedure to change variables names from $this_variable_style to $thisVariableStyle.

The commands below define these mappings:

  • +   Find the next $variable_with_underscores.
  • _   Convert the next underscore on the current line.

When required, you can yank the following lines in Vim (on the first line, type 2Y), then execute them (type @") to map the + and _ keys.

:nnoremap + /\$\w\+_<CR>
:nnoremap _ f_x~

Now you can press + to search for the next $variable_with_underscores, then press _ to find and delete the next underscore and toggle the case of the next character. Repeatedly press _ until all underscores are processed, then press + to find the next variable. For example, you may type +__+_+___ to skip through a file.

Type +~ for initial capitals.

The simple procedure above is suitable for manually changing a small number of variables, while inspecting each change. Using a substitute, the process can be automated. The following command will change all variables names from $this_variable_style to $thisVariableStyle:

:%s#\%($\%(\k\+\)\)\@<=_\(\k\)#\u\1#g

If wanted, the \v (very magic) option can be used to reduce the number of backslashes, and the conventional / can be used as the delimiter instead of #. The following command is equivalent to the above:

:%s/\v%(\$%(\k+))@<=_(\k)/\u\1/g

Change under_scores to CamelCase

The following mapping changes the visually selected text.

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

To use this you would go into Visual Mode (press v) then select the word (iw, which stands for inner word) then type ,c in visual mode.

This changes this_is_my_func to ThisIsMyFunc.

If you want the style to be thisIsMyFunc you can remove the gUl which changes the first character to Uppercase.

How it works

It substitutes the characters so that _a becomes A. The \u\1 uppercases the match. The <CR> hits the enter key for you and the cursor ends up at the beginning of the selection. We use gUl to Uppercase the character under the cursor.

Some might have used the ~ (tilde) to uppercase it, but if it was already uppercase it would have made it lowercase. Also, the tilde moves the cursor to the right which is not what we want.

Change CamelCase to under_scores

The following mapping changes the visually selected text.

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

This changes ThisIsMyFunc to this_is_my_func.

How it works

It substitutes the characters so that A becomes _a. The \_ put in the underscore the \l\1 (which difficult to see that the first is a lowercase L, the second is the number 1) forces the matched character to be lowercase.

The \<\@! tells substitute to ignore the first match. The gul changes the character under the cursor to be lower-case.

See also

Comments

Bugs

I have checked my previous comments from September 2010 (which I have replaced with the following).

The content in the Change under_scores to CamelCase and Change CamelCase to under_scores sections is broken (not worth saving):

  • The visual mappings are completely misguided becuase the substitute commands operate on whole lines (the substitute does not apply only to the selected text).
  • Would need \%V before and after pattern to fix previous bug.
  • The patterns should use \C otherwise the mappings totally break if someone has done :set ignorecase.
  • The gUl and gul code (which could be vU or vu) is hopeless: it is intended to convert the first character of the name after doing the substitute, but the substitute positions the cursor on the first nonblank character in the line (which may or may not be the first character of the variable name).
  • The ,u mapping converts a name like CONSTANT to C_o_n_s_t_a_n_t.

JohnBeckett 10:56, June 11, 2011 (UTC)

Proposal

I've given these a bit of a test, but it would be nice if someone would try them out.

Replace Change under_scores to CamelCase with following.

" Convert each name_like_this to NameLikeThis in current line.
:s#\(\%(\<\l\+\)\%(_\)\@=\)\|_\(\l\)#\u\1\2#g

" Convert each name_like_this to nameLikeThis in current line.
:s#_\(\l\)#\u\1#g

" Test (first line is original; second and third are results from above).
" CONSTANT ab_cd_ef some words name_like_this and another_name = some_more
" CONSTANT AbCdEf some words NameLikeThis and AnotherName = SomeMore
" CONSTANT abCdEf some words nameLikeThis and anotherName = someMore

Replace Change CamelCase to under_scores with following.

" Convert each NameLikeThis to name_like_this in current line.
" Better add 'c' (confirm) flag if use '%' (whole buffer).
:s#\(\<\u\l\+\|\l\+\)\(\u\)#\l\1_\l\2#g

" Alternative: accept numbers in name.
:s#\C\(\<\u[a-z0-9]\+\|[a-z0-9]\+\)\(\u\)#\l\1_\l\2#g

" Test (first line is original; second is result from above).
" CONSTANT AbCdEf some words NameLikeThis and AnotherName = someMore
" CONSTANT ab_cd_ef some words name_like_this and another_name = some_more

JohnBeckett 10:56, June 11, 2011 (UTC)

Advertisement