For instance, :echo strftime(%c)
will show the current time on the bottom, but how to insert this time string into the text (right after the cursor)?

- 8,239

- 1,362
-
It's also worth mentioning that this is not the same question as Writing a vim function to insert a block of static text, however some of the answers still apply. – Alastair Irvine Jan 19 '15 at 10:27
-
See also redirecting into a register: https://stackoverflow.com/questions/2573021/how-to-redirect-ex-command-output-into-current-buffer-or-file/4283053#4283053 – NeilG Oct 02 '19 at 02:04
9 Answers
:r!date +\%c
see :help :r!
Note, this is for external commands (they run in your shell), not vim commands.

- 4,165

- 85,964
-
5
date
is an external command and!
calls external commands while OP asks for vim commands. – Eelvex Feb 25 '11 at 08:51 -
3@eelvex no he didn't. and the ! is a vim, and vi, command. This is the canonical method. Works for many other things as well. – Keith Feb 25 '11 at 11:29
-
6@Keith: yes
!
is a vi(m) command that calls external commands. You may be right OP not wanting to output only vim commands but if (s)he does,!
will not do. – Eelvex Feb 25 '11 at 17:19 -
2You can combine the output of the external command with text you define. For example, the following adds two pound signs and the date of next Tuesday ("## Tuesday, 2020-06-23"):
:exe 'r!date --date="next Tuesday" "+\%A, \%Y-\%m-\%d"' | normal I##
– Matthias Braun Jun 21 '20 at 17:39 -
@Keith No they did not. OP clearly gave an example of a vim command, not a shell command. – adamency Mar 02 '23 at 15:29
You can use the expression register, "=
, with p
(or P
) in normal mode or <C-R>
in insert mode:
In normal mode:
(<C-M>
here means Control+M, or just press Enter/Return)
"=strftime('%c')<C-M>p
In insert mode:
(<C-M>
has the same meaning as above, <C-R>
means Control+R)
<C-R>=strftime('%c')<C-M>
If you want to insert the result of the same expression many times, then you might want to map them onto keys in your .vimrc
:
(here the <C-M>
and <C-R>
should be typed literally (a sequence of five printable characters—Vim will translate them internally))
:nmap <F2> "=strftime('%c')<C-M>p
:imap <F2> <C-R>=strftime('%c')<C-M>

- 20,101
-
3
-
3to get the value of a vim variable (for example, sessionoptions):
<C-R>=&sessionoptions
-- it even does wildmode tab-completion! – Justin M. Keyes Oct 25 '12 at 18:22 -
6
-
In insert mode, using
<c-r>=
is slow for command which may have a lot of output and also may break indent so that the output text is unreadable. For example,<c-r>=execute('nmap')
, the output will be written line by line, which is very slow. – jdhao Apr 24 '19 at 08:51 -
For some reason, this just doesn't work for me. Any ideas why it wouldn't work? – trusktr Dec 28 '20 at 22:48
-
Here is now to insert from normal mode without creating a new line:
:nmap F2 a<C-r>=strftime('%c')<C-m><C-c>
(For visual mode, usevmap
andc
instead ofa
) – Martin Braun Sep 30 '22 at 18:32
If you want to insert the output of a vim command (just like stdout in shell, and as opposed to the return value of a function call or an expression), you have to capture it. This is accomplished via the :redir
command, which allows you to redirect vim's equivalent of standard output into a variable, file, register, or other target.
:redir
is sort of painfully inconvenient to use; I would write a function to encapsulate its functionality in a more convenient way, something like
funct! Exec(command)
redir =>output
silent exec a:command
redir END
return output
endfunct!
Once you've declared such a function, you can use the expression register (as explained by Chris Johnsen) to insert the output of a command at the cursor position. So, from normal mode, hit :put =Exec('ls')
to insert the list of vim's current buffers.
Be aware that the command will execute in the function namespace, so if you use a global variable you will have to explicitly namespace it by prefixing it with g:
. Also note that Exec()
, as written above, will append a terminating newline to even one-line output. You might want to add a call to substitute()
into the function to avoid this.
Also see https://stackoverflow.com/questions/2573021/vim-how-to-redirect-ex-command-output-into-current-buffer-or-file/2573054#2573054 for more blathering on about redir
and a link to a related command.
-
2This works great. I added a
set paste
command before returning the output and aset nopaste
after, to avoid the staircase indent when the lines start with blanks. Actually, I wanted to save the value of the current paste option and to return it but I was unable to do it so. – Juan Lanus Jan 05 '15 at 21:17 -
1@JuanLanus The
set nopaste
shouldn't work afterreturn output
, because the return statement is an exit point out of the function. I've put my solution to this problem as a separate answer on this page. – Evgeni Sergeev Apr 23 '15 at 04:57 -
Instead of i^R=Exec('ls')
, try:put =Exec('ls')
. That should avoid the need to for setpaste. – idbrii Apr 26 '20 at 20:29
These commands will insert the output of strftime("%c")
right where your cursor is:
:exe ":normal i" . strftime("%c")
and
:call feedkeys("i". strftime("%c"))
There are other ways to do what you want (like, for example, those on Mikel's answer).
Edit: Even better, for in-place insert, use the =
register as Chris Johnsen describes
-
How can we pipe vim command output (f.e. output of
echo "foo"
, instead ofstrftime("%c")
) to the buffer? – trusktr Dec 28 '20 at 22:47 -
:call append(line('.'), strftime("%c"))
Will put it on the next line, then you could press J
(Shift+J)to join it up to the current position.
Or if you need it all in one command, you could do
:call setline(line('.'), getline(line('.')) . strftime("%c"))
or
:call setline(line('.'), getline(line('.')) . " " . strftime("%c"))
depending on whether you want a space inserted before the date or not.

- 57,299
- 15
- 134
- 153
You can use :put
with the expression register =
:
:put =strftime('%c')
This method allows you to make an alternative command to :echo
called :InsertExpr
that would insert your expression:
command! -nargs=* InsertExpr put =<args>
Or to insert commands like :ls
:
command! -nargs=* InsertCmd put =execute('<args>')
(Not sure why I can't get q-args to work.)
Usage:
:InsertExpr strftime('%c')
:InsertCmd ls

- 231
Improving @intuited answer to avoid the problem with leading whitespace and growing indent:
"Examples:
":call Exec('buffers')
"This will include the output of :buffers into the current buffer.
"
"Also try:
":call Exec('ls')
":call Exec('autocmd')
"
funct! Exec(command)
redir =>output
silent exec a:command
redir END
let @o = output
execute "put o"
return ''
endfunct!
This will simply insert at the current location in the file when you :call Exec('command')
from normal mode. As noted in the comment, the original (insert-mode) Ctrl+R =Exec('command')
approach with Exec(..)
returning a string could be partially corrected by using set paste
, but doesn't offer an opportunity to put the set nopaste
anywhere.
The let @o = output
syntax sets the register o
to the contents of the variable output
, as explained here: https://stackoverflow.com/a/22738310/1143274
The return ''
line is so that the default return value of 0
doesn't get inserted to the buffer.

- 282

- 1,371
- 3
- 10
- 9
This is how I do it. It puts it right after the cursor because it uses p
.
" save previous yank
let reg_save = @@
" save your text to the '@' register
let @@ = strftime('%c')
" paste it after the cursor
exec "normal! p"
" restore previous yank
let @@ = reg_save

- 121