Inserting output of Ex command into buffer

22 views
Skip to first unread message

Spiros Bousbouras

unread,
Apr 9, 2011, 1:11:08 PM4/9/11
to vim_use
How can you insert the output of an Ex command into the buffer at the
place where the cursor is ? Say for example in the 1st line here I
want
to insert right after "you" the output of :chdir .So I place the
cursor after "you" and then do what ?

Tim Chase

unread,
Apr 9, 2011, 1:29:12 PM4/9/11
to vim...@googlegroups.com, Spiros Bousbouras

A couple options occur:

1) use :redir to a register and paste the register contents:

:redir @a
:chdir
:redir END
"ap

2) use the system() call in an expression-register to perform the
command in your OS's command-interpreter:

In insert mode in *nix:
^R=system('pwd')

In insert mode in Win32:
^R=system('cd')

In normal mode in *nix:
"=system('pwd')<cr>p

In normal mode in Win32:
"=system('cd')<cr>p

where "^R" is control+R and "<cr>" is hitting <enter>.

For more info, you can read up at

:help :redir
:help i_CTRL-R
:help @=

As a caveat, most of those end up being line-wise and have odd
behaviors if your pulled-contents have a trailing newline (which
is most of the time).

-tim


Spiros Bousbouras

unread,
Apr 10, 2011, 6:39:30 PM4/10/11
to vim_use, Tim Chase, Spiros Bousbouras
On Apr 9, 6:29 pm, Tim Chase <v...@tim.thechases.com> wrote:
> On 04/09/2011 12:11 PM, Spiros Bousbouras wrote:
>
> > How can you insert the output of an Ex command into the buffer
> > at the place where the cursor is ? Say for example in the 1st
> > line here I want to insert right after "you" the output of
> > :chdir .So I place the cursor after "you" and then do what ?
>
> A couple options occur:
>
> 1) use :redir to a register and paste the register contents:
>
> :redir @a
> :chdir
> :redir END
> "ap

Strange that there isn't a simpler method built-in. And of
course if there is already a redirect going on this will mess
things up.

> 2) use the system() call in an expression-register to perform the
> command in your OS's command-interpreter:
>
> In insert mode in *nix:
> ^R=system('pwd')

I'm on Linux. This works for my specific example but not for
arbitrary vim commands. For example it won't work for
:swapname .

[...]

Tim Chase

unread,
Apr 10, 2011, 7:47:01 PM4/10/11
to Spiros Bousbouras, vim_use
On 04/10/2011 05:39 PM, Spiros Bousbouras wrote:
> On Apr 9, 6:29 pm, Tim Chase<v...@tim.thechases.com> wrote:
>> On 04/09/2011 12:11 PM, Spiros Bousbouras wrote:
>>> How can you insert the output of an Ex command into the
>>> buffer at the place where the cursor is?
>>
>> 1) use :redir to a register and paste the register
>> contents:
>
> Strange that there isn't a simpler method built-in.

I'm not sure it's *that* strange -- using ":redir" is the
canonical way to access the messages Vim produces, and Vim gives
plenty of options for redirection (files/registers/variables, and
appending/overwriting). I could see adding a hist-names (":help
hist-names") entry for messages to allow access to the
message-history list which would then allow you to insert it via
something like ^R=histget('messages')

That said, I could count on one hand[*] the number of times in 10
years of using Vim that I've wanted to include the output of a
vim command in my text, and

> And of course if there is already a redirect going on this
> will mess things up.

exactly 0 of those times have I been using :redir for something
else at the same time.

-tim

[*] okay, it might be cheating that I often count in binary on my
fingers, but that's still less than 32 :)

Spiros Bousbouras

unread,
Apr 12, 2011, 5:00:32 PM4/12/11
to vim_use
On Apr 10, 7:47 pm, Tim Chase <v...@tim.thechases.com> wrote:
> On 04/10/2011 05:39 PM, Spiros Bousbouras wrote:
>
> > On Apr 9, 6:29 pm, Tim Chase <v...@tim.thechases.com> wrote:
> >> On 04/09/2011 12:11 PM, Spiros Bousbouras wrote:
> >>> How can you insert the output of an Ex command into the
> >>> buffer at the place where the cursor is?
>
> >> 1) use :redir to a register and paste the register
> >> contents:
>
> > Strange that there isn't a simpler method built-in.
>
> I'm not sure it's *that* strange -- using ":redir" is the
> canonical way to access the messages Vim produces, and Vim gives
> plenty of options for redirection (files/registers/variables, and
> appending/overwriting).

Still , it's less convenient than system() so vim makes it
easier to get the output of external commands than vim
commands.

> I could see adding a hist-names (":help
> hist-names") entry for messages to allow access to the
> message-history list which would then allow you to insert it via
> something like ^R=histget('messages')

I would prefer a vsystem() function (vim system) or whatever
you want to call it so that for example you could do
^R=vsystem("swapname")

> That said, I could count on one hand[*] the number of times in 10
> years of using Vim that I've wanted to include the output of a
> vim command in my text, and

Ahhh , but perhaps your brain subconsciously filtered out such
possibilities because it realised that it's not easy to do ;-)

[...]

Charles E Campbell Jr

unread,
Apr 12, 2011, 9:32:06 PM4/12/11
to vim...@googlegroups.com
Spiros Bousbouras wrote:
> [snip]

> I would prefer a vsystem() function (vim system) or whatever
> you want to call it so that for example you could do
> ^R=vsystem("swapname")
>
[snip]

Why not try your hand at writing a function to do that? Admittedly, it
would have to begin with a capital letter.

Regards,
Chip Campbell

ZyX

unread,
Apr 12, 2011, 11:35:44 PM4/12/11
to vim...@googlegroups.com
Reply to message «Re: Inserting output of Ex command into buffer»,
sent 05:32:06 13 April 2011, Wednesday
by Charles E Campbell Jr:

> Why not try your hand at writing a function to do that? Admittedly, it
> would have to begin with a capital letter.

It is not possible: Vsystem("redir @a> | echom 'abc' | redir END") won't work.

Original message:

signature.asc

Gary Johnson

unread,
Apr 13, 2011, 1:19:09 AM4/13/11
to vim...@googlegroups.com
On 2011-04-13, ZyX wrote:
> Reply to message �Re: Inserting output of Ex command into buffer�,
> sent 05:32:06 13 April 2011, Wednesday
> by Charles E Campbell Jr:

> > Spiros Bousbouras wrote:


> > > [snip]
> > > I would prefer a vsystem() function (vim system) or whatever
> > > you want to call it so that for example you could do
> > > ^R=vsystem("swapname")
> >
> > [snip]
> >
> > Why not try your hand at writing a function to do that? Admittedly, it
> > would have to begin with a capital letter.

> It is not possible: Vsystem("redir @a> | echom 'abc' | redir END") won't work.

If one were writing a function as Chip suggested, one would put the
redir commands in the body of the function, not in the argument.

Regards,
Gary


Alessandro Antonello

unread,
Apr 13, 2011, 9:01:35 AM4/13/11
to vim...@googlegroups.com
2011/4/12 Spiros Bousbouras <spi...@gmail.com>:

> On Apr 10, 7:47 pm, Tim Chase <v...@tim.thechases.com> wrote:
>> On 04/10/2011 05:39 PM, Spiros Bousbouras wrote:
>>
>> > On Apr 9, 6:29 pm, Tim Chase <v...@tim.thechases.com>  wrote:
>> >> On 04/09/2011 12:11 PM, Spiros Bousbouras wrote:
>> >>> How can you insert the output of an Ex command into the
>> >>> buffer at the place where the cursor is?
>>
>> >> 1) use :redir to a register and paste the register
>> >> contents:
>>
>> > Strange that there isn't a simpler method built-in.
>>

I totally agree with you. Would be much more simpler if we could wrote
something like:

:<echo 25*47

And the output was directly put in the current buffer in the cursor position.
The sequence "redir 'something'", type a command and then 'redir END' is
really to much to do when we need to be fast. To get the result of the
calculation above is much more easy just "see" the value in the command window
and write it by your hand in the buffer.

This is a feature that a miss in Vim/GVim for quite sometime.

Regards.

Christian Brabandt

unread,
Apr 13, 2011, 9:51:14 AM4/13/11
to vim...@googlegroups.com
On Wed, April 13, 2011 3:01 pm, Alessandro Antonello wrote:
> I totally agree with you. Would be much more simpler if we could wrote
> something like:
>
> :<echo 25*47
>
> And the output was directly put in the current buffer in the cursor
> position.
> The sequence "redir 'something'", type a command and then 'redir END' is
> really to much to do when we need to be fast. To get the result of the
> calculation above is much more easy just "see" the value in the command
> window
> and write it by your hand in the buffer.
>
> This is a feature that a miss in Vim/GVim for quite sometime.

The above is already possible in vim.
in insert mode press <Ctrl-R>=25*47 and that's it.

:h i_CTRL-R_=

regards,
Christian

Jürgen Krämer

unread,
Apr 13, 2011, 9:52:36 AM4/13/11
to vim...@googlegroups.com

Hi,

you can insert the output of every VimL expression with

<C-R>=your-expression-goes-here<CR>

while you are in insert mode. Your example would then be typed as

<C-R>=25*47<CR>

Regards,
J�rgen

--
Sometimes I think the surest sign that intelligent life exists elsewhere
in the universe is that none of it has tried to contact us. (Calvin)

Charles Campbell

unread,
Apr 13, 2011, 9:54:15 AM4/13/11
to vim...@googlegroups.com
As a further hint -- the Dredir command in the Decho.vim debugging
package already does something similar.
( http://mysite.verizon.net/astronaut/vim/index.html#DECHO )

Regards,
Chip Campbell

Tony Mechelynck

unread,
Apr 13, 2011, 10:22:57 AM4/13/11
to vim...@googlegroups.com, Alessandro Antonello

For this particular use case (insert the value of an expression) you can
do it by means of the expression register:

in Insert mode
^R=25 * 47
(where ^R is a Ctrl-R keystroke), followed by Enter, or in Normal mode
"=25 * 47↓p
where ↓ represents a press on the Enter key.

See :help quote=


Best regards,
Tony.
--
Real computer scientists don't comment their code. The identifiers are
so long they can't afford the disk space.

Spiros Bousbouras

unread,
Apr 13, 2011, 10:53:25 AM4/13/11
to vim_use
On Apr 10, 11:39 pm, Spiros Bousbouras <spi...@gmail.com> wrote:
> On Apr 9, 6:29 pm, Tim Chase <v...@tim.thechases.com> wrote:
>
> > On 04/09/2011 12:11 PM, Spiros Bousbouras wrote:
>
> > > How can you insert the output of an Ex command into the buffer
> > > at the place where the cursor is ? Say for example in the 1st
> > > line here I want to insert right after "you" the output of
> > > :chdir .So I place the cursor after "you" and then do what ?

[...]

> > 2) use the system() call in an expression-register to perform the
> > command in your OS's command-interpreter:
>
> > In insert mode in *nix:
> > ^R=system('pwd')
>
> I'm on Linux. This works for my specific example

For this example ^R=getcwd() also works.

Tim Chase

unread,
Apr 13, 2011, 10:53:31 AM4/13/11
to vim...@googlegroups.com, Jürgen Krämer
On 04/13/2011 08:52 AM, J�rgen Kr�mer wrote:
>>>>>>> How can you insert the output of an Ex command into the
>>>>>>> buffer at the place where the cursor is?
>>>>
>>>>>> 1) use :redir to a register and paste the register
>>>>>> contents:
>>>>
>>>>> Strange that there isn't a simpler method built-in.
>>>>
>>
>> I totally agree with you. Would be much more simpler if we could wrote
>> something like:
>>
>> :<echo 25*47
>>
>> And the output was directly put in the current buffer in the cursor position.
>> The sequence "redir 'something'", type a command and then 'redir END' is
>> really to much to do when we need to be fast. To get the result of the
>> calculation above is much more easy just "see" the value in the command window
>> and write it by your hand in the buffer.
>>
>> This is a feature that a miss in Vim/GVim for quite sometime.
>
> you can insert the output of every VimL expression with
>
> <C-R>=your-expression-goes-here<CR>
>
> while you are in insert mode. Your example would then be typed as
>
> <C-R>=25*47<CR>

While this works for expressions (the followup question about
"echo 25*47"), it doesn't satisfy the OP's request for arbitrary
Ex commands. Assuming the commands to be executed don't include
redirs and there's not a redir already in process (that you don't
want to terminate), it could be wrapped in a function

function! Capture(excmds)
redir => s:results
exec a:excmds
redir END
return s:results
endfunction

You could then use the function in concert with the expression
register:

<c-r>=Capture('scriptnames')

(odd results if you don't have 'paste' set) in insert mode, or
you can use

"<c-r>=Capture('scriptnames')<cr>p

to paste it in normal mode. The command should also work with
multiple pipe-separated commands:

Capture('scriptnames|set')

Hope this helps,

-tim


ZyX

unread,
Apr 13, 2011, 11:05:21 AM4/13/11
to vim...@googlegroups.com
Reply to message «Re: Inserting output of Ex command into buffer»,
sent 09:19:09 13 April 2011, Wednesday
by Gary Johnson:

> If one were writing a function as Chip suggested, one would put the
> redir commands in the body of the function, not in the argument.

I do understand this: I meant that if function argument calls redir itself then
redir inside Vsystem function won't work.

Original message:

signature.asc

Spiros Bousbouras

unread,
Apr 13, 2011, 12:08:13 PM4/13/11
to vim_use, Tim Chase, Jürgen Krämer
On Apr 13, 3:53 pm, Tim Chase <v...@tim.thechases.com> wrote:
>
> While this works for expressions (the followup question about
> "echo 25*47"), it doesn't satisfy the OP's request for
> arbitrary > Ex commands. Assuming the commands to be executed
> don't include redirs and there's not a redir already in process
> (that you don't want to terminate), it could be wrapped in a function
>
> function! Capture(excmds)
> redir => s:results
> exec a:excmds
> redir END
> return s:results
> endfunction

Regarding the situation where excmds contains redirections i.e.
the example Vsystem("redir @a> | echom 'abc' | redir END")
posted earlier by ZyX , I don't consider it a problem. I hadn't
thought of this scenario when I suggested Vsystem() but it
makes more sense to me that if some commands in Vsystem's
argument redirect their output then this output should not be
included in Vsystem's return value.

Consider the analogous situation with shell programming:

prompt> shell-script
...
Get stuff on the screen
...

prompt> shell-script > file1
Now stdout goes into file1

But if inside shell-script there is somewhere
command > file2

then the output of command will still go to file2 even when I
do shell-script > file1


On the other hand , the fact that Capture() will mess up any
redirection set up before calling Capture() is a problem. I
don't think there's a way to solve this with what vim presently
offers.

[...]

> Hope this helps,

It's good enough for government work. Thank you.

Spiros Bousbouras

unread,
Apr 13, 2011, 12:10:42 PM4/13/11
to vim_use
On Apr 13, 3:53 pm, Tim Chase <v...@tim.thechases.com> wrote:
>
> While this works for expressions (the followup question about
> "echo 25*47"), it doesn't satisfy the OP's request for arbitrary
> Ex commands. Assuming the commands to be executed don't include
> redirs and there's not a redir already in process (that you don't
> want to terminate), it could be wrapped in a function
>
> function! Capture(excmds)
> redir => s:results
> exec a:excmds
> redir END
> return s:results
> endfunction

Forgot to ask , why not use a local variable i.e. l:results ?

Tim Chase

unread,
Apr 13, 2011, 1:18:11 PM4/13/11
to vim...@googlegroups.com, Spiros Bousbouras
On 04/13/2011 11:10 AM, Spiros Bousbouras wrote:
> Forgot to ask , why not use a local variable i.e. l:results?

I suppose either would do -- l:results would work just as well.
I was just grabbing for something that wouldn't leak into globals.

>> Hope this helps,
>
> It's good enough for government work. Thank you.

Sorry...If I knew I was aiming for government work, I would have
provided a horribly baroque user-interface, overcharged, come in
way over budget, and taken 3 years over estimate to provide
something that didn't quite work right. :)

-tim (who used to work for a large contracting company where that
was the unfortunate way things ran. SOOooo glad to be outta there)

Spiros Bousbouras

unread,
Apr 13, 2011, 8:15:06 PM4/13/11
to vim_use, Spiros Bousbouras, Tim Chase, Jürgen Krämer
On Apr 13, 5:08 pm, Spiros Bousbouras <spi...@gmail.com> wrote:
> On Apr 13, 3:53 pm, Tim Chase <v...@tim.thechases.com> wrote:
>
> > While this works for expressions (the followup question about
> > "echo 25*47"), it doesn't satisfy the OP's request for
> > arbitrary > Ex commands. Assuming the commands to be executed
> > don't include redirs and there's not a redir already in process
> > (that you don't want to terminate), it could be wrapped in a function
>
> > function! Capture(excmds)
> > redir => s:results
> > exec a:excmds
> > redir END
> > return s:results
> > endfunction
>
> Regarding the situation where excmds contains redirections i.e.
> the example Vsystem("redir @a> | echom 'abc' | redir END")
> posted earlier by ZyX , I don't consider it a problem. I hadn't
> thought of this scenario when I suggested Vsystem() but it
> makes more sense to me that if some commands in Vsystem's
> argument redirect their output then this output should not be
> included in Vsystem's return value.
>
> Consider the analogous situation with shell programming:

Ok , with more thought I see that it is a problem. Consider
Vsystem("command1 | redir @a> | echom 'abc' | redir END | command2")

The return value of Vsystem() should include the output of
command1 and command2 but it won't.

Tim Chase

unread,
Apr 13, 2011, 8:27:37 PM4/13/11
to Spiros Bousbouras, vim_use, Jürgen Krämer
On 04/13/2011 07:15 PM, Spiros Bousbouras wrote:
>> Consider the analogous situation with shell programming:
>
> Ok , with more thought I see that it is a problem. Consider
> Vsystem("command1 | redir @a> | echom 'abc' | redir END | command2")
>
> The return value of Vsystem() should include the output of
> command1 and command2 but it won't.

Right...I don't think Vim has a means by which to detect if/where
redirection is occurring so it can be saved and restored. So
it's a classic case of

Patient: "Doctor, it hurts when I do this..."
Doctor: "Well, don't do that!"

where in this case, the "do this" is nested redirection. :)

-tim


Andy Wokula

unread,
Apr 15, 2011, 6:54:37 AM4/15/11
to vim...@googlegroups.com

When following some convention, nesting can be enabled, see attachment.
(must not use :redir directly, only StrRedir() -- where "StrRedir" is my
name for "Vsystem").

Attachment defines two commands, both use StrRedir().

:FiltRedir {cmd} {pattern}
echo the output of {cmd}, filtered by {pattern}

:PutRedir {cmd}
:put the output of {cmd} into the buffer


Example with nested call to StrRedir():

:PutRedir FiltRedir scrip \<plug

Puts the output of :scriptnames into the buffer, filtered to lines
matching '\<plug'.

--
Andy

redir_nested.zip
Reply all
Reply to author
Forward
0 new messages