5

In C you can do something like this:

int foo(int a) { return a + 1; }
int main(void) {
    int a = 0;
    while ((a = foo(a)) < 10) {
        /* */
    }
}

How can I do the same thing in vimscript, i.e. something like this:

function! s:foo()
    let l:foo = 0
    while (let l:foo = l:foo + 1) < 10)
        echo 'hi'
    endwhile
endfunction

i.e. I want to make the while loop dependent on a value that is assigned anew with every loop. You could do this with traditional for or do-while loops, but sadly Vimscript doesn't have these. One way I see how you can do this is, is like this:

function! s:foo()
    let l:foo = 0

    while l:foo + 1 < 10
        let l:foo = l:foo + 1
        echo 'hi'
    endwhile
endfunction

But if the operation is expensive and you need to make more than one comparison (is it equal to 5, 7, or 12, etc), this gets ridiculous pretty quickly.

There must be a better way to do this...

9

You can't. Every line in the script is the same as running it in the command window (e.g. :while 1 | echo 'hi' | endwhile). The :while command evaluates a boolean/numeric expression to the right of it, and :let is a command that defines a variable. Commands don't return a value.

The for...endfor loop is the only loop that I know of that will create variables if you're iterating over a sequence, like for i in range(10).

If your loop condition is really going to be complicated you could use an indefinite loop and break when your condition is met:

let foo = 0

while 1
  if foo + 1 >= 10 || s:other_condition()
    break
  endif
  let foo += 1
  echo 'hi'
endwhile

Or

let done = 0
let foo = 1

while !done
  let foo += 1
  echo 'hi'
  let done = foo + 1 > 10 || s:other_condition()
endwhile

IMO, both are the equivalent of what you're wanting to accomplish. Except that in the second one, you can't thoughtlessly continue from anywhere in the body.

| improve this answer | |

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.