Ein
Ein

Reputation: 1603

In vim, how do I redirect the output of a vimscript function?

I have this vimscript function

 function! Env()
     redir => s
     sil! exe "norm!:ec$\<c-a>'\<c-b>\<right>\<right>\<del>'\<cr>"
     redir END
     return split(s)
 endfunction

This function was obtained from this question:
How to list all the environment variables in Vim?

When I do :call Env() I don't see any output, but :echo Env() displays as output the names of all environment variables.

I'd rather copy and paste this output somehow. I know about :redir. However this doesn't work:

:redir @A
:echo Env()
:redir END
"ap

Instead, a blank line is pasted.

I have tried many combinations of the :redir command (to registers and/or files) and variations on call Env() without success. Is this because the output generated is from calling a function? I thought it might be because the function returns a list, but :echo string(Env()) isn't captured by :redir either.

Edit: This is the modified solution I used from the answer below.

function! Env()
    redir => s
    sil! exe "norm!:ec$\<c-a>'\<c-b>\<right>\<right>\<del>'\<cr>"
    redir END
    let @s = string(split(s))
endfunction

One can then execute :call Env() and then "sp to paste.

related question:
How to redirect ex command output into current buffer or file?

Upvotes: 2

Views: 3252

Answers (2)

Aaron Thoma
Aaron Thoma

Reputation: 4026

:let @a+=Env()

instead of

:redir @A
:echo Env()
:redir END

is much more concise, but doesn't print Env()'s output to the screen.

(The asker @Ein's modified solution does neither.)

Upvotes: 0

glts
glts

Reputation: 22684

As I said in the comment, this is a problem with :redir that's being discussed on vim_dev. In short, nested redirection with :redir isn't possible.

But of course you can simply modify your Env() function to redirect output to a register or global variable.

Just change redir => s to either redir => g:s (global variable g:s) or redir @s (register s), and remove the return statement. Let's use the register:

function! Env()
    redir @s
    sil! exe "norm!:ec$\<c-a>'\<c-b>\<right>\<right>\<del>'\<cr>"
    redir END
endfunction

After calling the function, the output is stored in register s and you can put it with "sp, of course.

Upvotes: 2

Related Questions