0

I have line of code like this one:

variableInCamelCase <- map["variableInCamelCase"]

I need to make it like this:

variable_In_Camel_Case <- map["variableInCameCase"]

Only the first word must be converted, I'm trying to find a regex to do it, and I need to do it in Vim but I can't. A regex like this one:

var rex = /([A-Z])([A-Z])([a-z])|([a-z])([A-Z])/g;

"CSVFilesAreCoolButTXT".replace( rex, '$1$4_$2$3$5' );

Is not good because I need to do it only on the first word. Plus, I need it for VIM which uses a special syntax to capture a group.

I tried something like this: s/\(\l\)\(\u\)/\1_\2/g, which is equivalent to ([a-z])([A-Z]), but I can't put it in OR with the ([A-Z])([A-Z])([a-z])

There is someone with a good vim ready regex for my problem? An explanation would be welcome also.

AR89
  • 3,548
  • 7
  • 31
  • 46
  • This is the best I can come up with so far. Unfortunately, it adds a trailing `_` after the variable name. I'm still thinking about whether there's a way around that. `s/\v([A-Z])([A-Z])([a-z])|([a-z])([A-Z])|( .*$)/\1\4_\2\3\5\6/g` – eddiem Oct 28 '16 at 21:43
  • This is an extremely hack solution, but you could do `qq:s/\v^\w{-}\a\zs\u/_&@qq@q` – DJMcMayhem Oct 28 '16 at 22:18
  • 1
    Tim Pope's [abolish](https://github.com/tpope/vim-abolish) can do it for you. – Sato Katsura Oct 29 '16 at 07:15

1 Answers1

1

I've got two commands to transform to snake_case from UpperCamelCase or lowerCamelCase, and the other way around, in lh-dev. One applies on the current word, the other works like substitute. Actually more naming choices are available if you configure the library for your current project (-> variables, attributes, constants, getters, types, etc).

How it works? Well it's using the lh#dev#naming#to_underscore() function in the case of CamelCase -> snake case.

This one is quite simple actually:

" Function:lh#dev#naming#to_underscore(identifier)         {{{3
function! lh#dev#naming#to_underscore(identifier)
  " first I make sure the first letter is in lower case
  let identifier = substitute(a:identifier, '\%(^\|[^A-Za-z0-9]\)\zs\(\u\)', '\l\1', '')
  " then I replace uppercase letters by '_' + their lower case flavour
  let identifier = substitute(identifier, '\l\zs\(\u\)', '_\l\1', 'g')
  return identifier
endfunction

Then, :[range]ConvertNames/pattern/policy/flag will be converted into something like :[range]substitute/pattern/\=lh#dev#naming#{snake}(submatch(0))/flags.

With a generic pattern like \w\+, it'll apply the transformation on the first word found -- the transformation being replacing the word found with its snake case form.

Luc Hermitte
  • 31,979
  • 7
  • 69
  • 83