1

I'm doing a project-wise refactor and I want to change variable names from camelCase to snake_case. I have YCM and vim-abolish installed. Let's say I have the following source file:

dueDate = ...
processDueDate(dueDate);
  • With vim-abolish I can press crs on every word to change them to snake case. The bad thing is this method is error prune. I can easily forget to change one of them and I will have errors.
  • With YCM, I can do :YcmCompleter RefactorRename due_date on dueDate and it will change all of the occurrences of dueDate to due_date which is good for me. The bad thing is I have to type the new variable name. This is a pain if the variable name is long.

I want to combine these two methods and map it to some key. Currently I have this:

nnoremap <leader>yr :YcmCompleter RefactorRename <C-R>=expand("<cword>")<CR>

Which is better than having nothing but I still need to delete some part of the expanded word and write it myself.

My question is how can I call vim-abolish's function on the expanded word? Tried the following one but obviously it didn't work:

nnoremap <leader>yr :YcmCompleter RefactorRename call <Plug>(abolish-coerce)<C-R>=expand("<cword>")<CR>
1
2

You'll have to reverse engineer the internal function used by Abolish and call it. It's quite likely one of the functions from the autoload plugin file that is part of abolish.

In the case of my lh-style plugin (which provides a feature similar to abolish, but which is also meant to provide a stable API to be used from other plugins), it would have been lh#naming#to_underscore() ->

nnoremap <leader>yr :<c-u>YcmCompleter RefactorRename <C-R>=lh#naming#to_underscore(expand("<cword>"))<CR>

Note that you could have used :%ConvertNames/^Rw/snake with lh-style, but I expect the refactoring from clang-complete to be smarter and work only on related symbols from the same translation unit, while lh-style command will work of every text that matches the regex in the current buffer.

EDIT: My mistake, abolish doesn't publish the function you need: https://github.com/tpope/vim-abolish/blob/master/plugin/abolish.vim#L120 It can be hacked. You'll need first to find the script id of plugin/abolish.vim (see this answer on SO on this topic ; BTW it means abolish needs to be loaded before the script where your mapping is defined), and then call the function named <SNR{thescriptid}_snakecase from the mapping you've have built on the fly. Another possibility consists in refactoring abolish to move the script functions in an autoload plugin and to contribute it back.

EDIT2: I stand corrected (thanks Peter!): Abolish exposes a way to convert to snake case with Abolish.Coercions.s(the_id_to_convert). IOW, what you're looking for could be done with

nnoremap <leader>yr :<c-u>YcmCompleter RefactorRename <C-R>=Abolish.Coercions.s(expand("<cword>"))<CR>

Note: while the trick with the commandline-window is really neat, I expect this version to be a little bit better (less side-effects from using opening and closing another window, a little bit faster...)

2
  • 2
    You can use Abolish.Coercions.s('fooBar') to convert to "snake_case". So this would become nnoremap <leader>yr :<c-u>YcmCompleter RefactorRename <C-R>=Abolish.Coercions.s(expand("<cword>"))<CR> Apr 28 at 13:32
  • I saw your last edit too late. Well, yes. I have to accept this answer. It's what I originally asked. But for now, I will go with the command-line approach as it doesn't require me to know which function do I need to use.
    – Asocia
    Apr 30 at 21:47
3

The command line window (q:, :<C-f>) is a convenient place to run normal vim commands when editing :-commands.

In this case, I would add to the mapping the opening of the command-line window and the usual crs. Some subtleties:

  • we need nmap to make crs work; normally we'd prefer nnoremap
  • <C-f> leaves the cursor where it is, and apparently it matters in this case, so we add b before crs
  • this leaves the command-line window open; you could add <cr> to run the command or <C-c> to drop back to the regular : line if you want. I would be inclined to just stay there, though
nmap <leader>yr :YcmCompleter RefactorRename <C-r>=expand('<cword>')<CR><C-f>bcrs

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.