0

I am trying to replace the entire buffer with the output from an external command. Similar to :% !myprog, but only if the command succeeds:

let output = system('myprog')
if v:shell_error == 0
    " What to do here?
    " How to replace entire buffer with the contents of output?
    " How to achieve exactly the same effect as ':% !myprog'?
else
    echoerr 'Command failed! Error message: ' . out
endif

To replace the entire buffer with the contents of the output variable, I tried :1,$d | put =output, but this is subtly different from the effect of % !myprog. Among other things, :1,$d | put =output inserts an unwanted newline, and the cursor position is different.

I am looking for a way to replace the entire buffer with the contents of a variable in exactly the same way that :% !myprog replaces the entire buffer with the output of an external command.

Update: I managed to achieve the desired effect using:

1,$d          " Delete contents of entire buffer.
0put =output  " Insert contents of variable without extra newline at the beginning.
$d            " Remove the extra newline at the end of the file.
call setpos('.', [0, 1, 1, 0])  " Move cursor to first line, first column.

This looks like a hack. Is there a better way?

  • 1
    You have setline() and append(), IIRC. I usually prefer. – Luc Hermitte Sep 19 at 10:45
2

Is there a better way?

In Vim there are always too many ways. I'd do it like this:

" get result as List
let output = systemlist('myprog')
if v:shell_error
    echoerr 'Command failed! Error message:' output[0]
else
    " add output on top
    call append(0, output)
    " delete the rest
    call deletebufline("%", len(output) + 1, "$")
    " go to first line, first column
    1
endif

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.