I wrote a patch to add new function 'capture()'.
When you want to get a list of all commands/functions/mappings with using vim script, probably, you'll do like follow.
---------------------------------
let funcs = ''
redir => funcs
silent! function
redir END
---------------------------------
I guess, most of vim script programmers want to get the result as expression. not command, want to get more easily.
If vim have 'capture()' which allow to getting those command line 'function', I guess this is very useful.
For example, getting :Command list as array.
---------------------------------
:echo map(split(capture("command"), "\n")[1:], 'split(v:val[4:])[0]')
---------------------------------
One more thing. vim doesn't support nest of :redir.
---------------------------------
function! s:foo()
let a = ''
redir => a
silent echo "foo"
redir END
return a
endfunction
function! s:bar()
let a = ''
redir => a
call s:foo()
redir END
return a
endfunction
echo s:bar()
---------------------------------
This 'echo s:bar()' doesn't show anything. But capture() can do it.
---------------------------------
echo capture("s:bar()")
foo
---------------------------------
capture() is working on sandbox. so you can't use this in modeline.
Below is a patch. How about this new feature?
https://gist.github.com/mattn/5449425
- Yasuhiro Matsumoto
> Probably a nice addition, but one can already do all of this in vimscript, see attachment.
> In your example, replace capture() with StrRedir().
No, it can't. It depend on your vim script. We want to get the result without side effect.
---------------------------------
function! s:bar()
let a = ''
redir => a
call thirdparty#library#function()
redir END
return a
endfunction
echo s:bar()
---------------------------------
Do you know the wheather thirdparty#library#function() call redir? or not?
I don't think all of vim script like the thirdparty#library#function() call your Redir function.
The functions in message.c write message with color attributes. So if splitting per line, it must get whole contents at the first.
I guess someone want to get the contents as text which contains \n, but someone want to get the contents as array of lines. So I want to keep the contents as text.
Thanks.
I don't hope that capture() contains highlight attributes. It should be plain text. And I guess fixing redir nesting has problems.
1. There are plugins that depend on original behavior. This break compatible.
2. If skipped 'redir END' with exceptions, we can't close the nesting.
For about 2, one of solution is adding bang like 'redir! END'. but this will close all of redir nesting. So it's become un-expected behavior.
Thanks.
- Yasuhiro Matsumoto
Refer to my message. Nested :redir throws an error only when context is switched, it is possible to have
redir => commands
command
redir => mappings
map
redir => imappings
imap
" and so on
redir END
> That's just bad coding practice, and it could easily be
> corrected in the plugin.
I completely agree there. Also refer to my message, I explained there how this situation may easily be worked around (just making it always write to target when any :redir is issued is enough for plugins to work; finishing redirections to local variables after function finishes will delete stale redirs in all cases that make sense to write from my point of view and even not finishing should be rare enough and not result in much harm: at maximum vim killed by OOM killer or a few MiBs long file). I have never actually seen plugins with the above code though.
I'm thinking capture() is not replacement of redir. So I'm thinking this issue should be separated with redir's issue.
1. The redir have a problem currently, But capture() doesn't.
2. Reasonable to implement.
3. Easy to use. Possible to write per one line.
4. I know there are some users who want capture().
I'm thinking it's good idea to solve some problem.
Thanks.