开发者

Vim: change formatting of variables in a script

I am using vim to edit a shell script (did not use the right coding standard). I need to change all of my variables from camel-hum-notation startTime to caps-and-underscore-notation START_TIME.

I do not want to change the way method names are represented.

I was thinking one way to do this would be to write a function and map it to a key. The function could do something like generating this on the command line:

s/<word under cursor>/<leave cursor here to type what to replace with>

I think that this function could be applyable to other situations which would be handy. Two questions:

Question 1: How would I go about creating that function.

    开发者_如何学编程
  • I have created functions in vim before the biggest thing I am clueless about is how to capture movement. Ie if you press dw in vim it will delete the rest of a word. How do you capture that?
  • Also can you leave an uncompleted command on the vim command line?

Question 2: Got a better solution for me? How would you approach this task?


  1. Use a plugin

    Check the COERCION section at the bottom of the page:

    http://www.vim.org/scripts/script.php?script_id=1545

  2. Get the :s command to the command line

    :nnoremap \c :%s/<C-r><C-w>/

    <C-r><C-w> gets the word under the cursor to command-line

  3. Change the word under the cursor with :s

    :nnoremap \c lb:s/\%#<C-r><C-w>/\=toupper(substitute(submatch(0), '\<\@!\u', '_&', 'g'))/<Cr>

    lb move right, then to beginning of the word. We need to do this to get the cursor before the word we wish to change because we want to change only the word under the cursor and the regex is anchored to the current cursor position. The moving around needs to be done because b at the start of a word moves to the start of the previous word.

    \%# match the current cursor position

    \= When the substitute string starts with "\=" the remainder is interpreted as an expression. :h sub-replace-\=

    submatch(0) Whole match for the :s command we are dealing with

    \< word boundary

    \@! do not match the previous atom (this is to not match at the start of a word. Without this, FooBar would be changed to _FOO_BAR)

    & in replace expressions, this means the whole match

  4. Change the word under the cursor, all matches in the file

    :nnoremap \a :%s/<C-r><C-w>/\=toupper(substitute(submatch(0), '\<\@!\u', '_&', 'g'))/g<Cr>

    See 3. for explanation.

  5. Change the word under the cursor with normal mode commands

    /\u<Cr> find next uppercase character

    i_ insert an underscore.

    nn Search the last searched string twice (two times because after exiting insert mode, you move back one character).

    . Repeat the last change, in this case inserting the underscore.

    Repeat nn. until all camelcases have an underscore added before them, that is, FooBarBaz has become Foo_Bar_Baz

    gUiw uppercase current inner word

  6. http://vim.wikia.com/wiki/Converting_variables_to_camelCase


I am not sure what you understand under 'capturing movements'. That said, for a starter, I'd use something like this for the function:

fu! ChangeWord()

  let l:the_word = expand('<cword>')

  " Modify according to your rules
  let l:new_var_name = toupper(l:the_word)

  normal b
  let l:col_b = col(".")

  normal e
  let l:col_e = col(".")

  let l:line = getline(".")

  let l:line = substitute(
  \ l:line, 
  \ '^\(' . repeat('.',  l:col_b-1) . '\)' . repeat('.', l:col_e - l:col_b+1), 
  \ '\1' . l:new_var_name, 
  \ '')

  call setline(".", l:line)

endfu

As to leaving an uncompleted command on the vim command line, I think you're after

:map ,x :call ChangeWord(

which then can be invoked in normal mode by pressing ,x.

Update

After thinking about it, this following function is a bit shorter:

fu! ChangeWordUnderCursor()

  let l:the_word = expand('<cword>')

  "" Modify according to your rules
  let l:new_var_name = '!' . toupper(l:the_word) . '!'

  normal b
  let l:col_b = col(".")

  normal e
  let l:col_e = col(".")

  let l:line = getline(".")

  exe 's/\%' . l:col_b . 'c.*\%' . (l:col_e+1) .'c/' . l:new_var_name . '/'

endfu
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜