How to repeatedly add text on both sides of a word

2019-04-30 02:31发布

问题:

I have a bunch of local variable references in a Python script that I want to pull from a dictionary instead. So, I need to essentially change foo, bar, and others into env['foo'], env['bar'] and so on. Do I need to write a regular expression and match each variable name to transform, or is there a more direct approach that I could just repeat with the . command?

回答1:

You can use a macro: type these commands in one go (with spacing just to insert comments)

             " first move to start of the relevant word (ie via search)
qa           " record macro into the a register.
ienv['<esc>  " insert relevant piece
ea']         " move to end of word and insert relevant piece
q            " stop recording

then, when you're on the next word, just hit @a to replay the macro (or even @@ to repeat the last replay after that).



回答2:

There's an easier way - you can use a regex search and replace. Go into cmdline mode by typing a colon and then run this command:

%s/\\(foo\|bar\|baz\\)/env['\1']/

Replacing foo, bar, and baz with whatever your actual variable names are. You can add as many additional variables as you'd like, just be sure to escape your OR pipes with a backslash. Hope that helps.



回答3:

you could write a function that would do this pretty well, add this to your .vimrc file:

function! s:surround()
    let word = expand("<cword>")
    let command = "%s/".word."/env[\'".word."\']/g"
    execute command
endfunction
map cx :call <SID>surround()<CR>

This will surround every occurance of the word currently under the cursor.

If you wanted to specify what went before and after each instance you could use this:

function! s:surround()
    let word = expand("<cword>")
    let before = input("what should go before? ")
    let after = input("what should go after? ")
    let command = "%s/".word."/".before.word.after."/g"
    execute command
endfunction
map cx :call <SID>surround()<CR>

If you only want to confirm each instance of the variable you could use this:

function! s:surround()
    let word = expand("<cword>")
    let before = input("what should go before? ")
    let after = input("what should go after? ")
    let command = "%s/".word."/".before.word.after."/c"
    execute command
endfunction
map cx :call <SID>surround()<CR>


回答4:

I figured out one way to do what I need. Use q{0-9a-zA-Z"} to record key strokes into a buffer. Position the cursor at the begging of the variable name, then cw and type env['']. Next move the cursor back one space to the last quote and paste the buffer filled from the cw command with P. Finally, reuse the recording with @{0-9a-z".=*} for each variable.



标签: vim editor vi