Take the 2-minute tour ×
Super User is a question and answer site for computer enthusiasts and power users. It's 100% free, no registration required.

The following is roughly what I am trying to do in vim

:let g:ID = 1
:%s/^/\= g:ID | let g:ID = g:ID * 1.2/

Now, it looks like vim disregrads everything after the bar (that is the let g:ID = g:ID * 1.2 part.

I could of course write a function that multiplies g:ID with 1.2 and returns g:ID's value, but I'd like to forego this.

Thanks Rene

edit for clarity:

In vim-script, I can write multiple statements on one line if I use the bar (|) to chain them. So, instead of

let g:ID = 20
let g:ID = g:ID * 1.2
let g:ID = g:ID * 1.2

I could also write

  let g:ID = 20 | let g:ID = g:ID * 1.2 | let g:ID = g:ID * 1.2

Now, the \= thingy allows me to substitute a regular expression with a vim script expression. For example, I could do a

:%s/ABC/\=line(".")/

which would replace every occurence of ABC in my current buffer with the line number on which it is found.

Similarly a

:%s/^/\=g:ID/

would write the current value of g:ID at the beginning of each line in my buffer.

That's all fine and dandy, but I'd like to have more than one expression in the replacement part and was wondering if I could achieve that by chaining such expressions with the bar. In my case, I'd like to manipulate g:ID after every substitution call, hence

:let g:ID=20
:s/^/\=g:ID|let g:ID=g:ID * 1.2/

would result in writing 20 at the beginning of the first line in my buffer, 24 at the beginning of the second line in my buffer, 28.8 at the beginning of the third line in my buffer and so on.

I hope I made myself clearer now.

share|improve this question
1  
it is not instantly obvious what you want to achieve ... –  akira Nov 5 '09 at 11:27
    
I want to chain two "commands" in the replacement part of a search-repacle pattern match. –  René Nyffenegger Nov 5 '09 at 22:23
    
obviously i wasnt clear about what i was trying to say: edit your question so it becomes clearer without the comments :) –  akira Nov 6 '09 at 6:24
add comment

3 Answers 3

up vote 2 down vote accepted

You can use :global as its command is executed for every line.

:let g:ID = 1
:g//s//\=g:ID/ | let g:ID = g:ID + 1

If you want to constrain the replacement, either limit by the :global pattern, or prefix :global with a range, or both.

:10,20g/foo/s/^/\=g:ID/ | let g:ID = g:ID + 1

That should prepend the incremented g:ID for every line that matches foo from line 10 to 20 (inclusive).

share|improve this answer
    
Thank you. Although I hoped there would be a "more direct" way, your answer comes closest to what I wanted. –  René Nyffenegger Apr 26 '11 at 23:17
add comment

You may need to define a function:

function! Accu(varname, mult)
  let old = {a:varname}
  let {a:varname} = {a:varname} * a:mult
  return old
endfunction

and use it this way:

:let g:ID = 1
:%s/^/\=Accu('g:ID', 1.2)/
share|improve this answer
    
Yes, I know that it is possible with a function. But sometimes I feel it's just not worth writing the function... that is, if I could go without... –  René Nyffenegger Nov 17 '09 at 22:21
add comment

Try <bar> instead of | Have a look at: http://vim.wikia.com/wiki/Best_Vim_Tips

share|improve this answer
    
<bar> instead of | results in E15: invalid expression : g:ID <bar> let g:ID = ... and a E121: undefined variable bar –  René Nyffenegger Nov 6 '09 at 10:21
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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