: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)?
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 IrvineJan 19, 2015 at 10:27
See also redirecting into a register: stackoverflow.com/questions/2573021/…– NeilGOct 2, 2019 at 2:04
Note, this is for external commands (they run in your shell), not vim commands.
dateis an external command and
!calls external commands while OP asks for vim commands. Feb 25, 2011 at 8: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.– KeithFeb 25, 2011 at 11:29
!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. Feb 25, 2011 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##Jun 21, 2020 at 17:39
@Keith No they did not. OP clearly gave an example of a vim command, not a shell command.– adamencyMar 2 at 15:29
You can use the expression register,
P) in normal mode or
<C-R> in insert mode:
In normal mode:
<C-M> here means Control+M, or just press Enter/Return)
In insert mode:
<C-M> has the same meaning as above,
<C-R> means Control+R)
If you want to insert the result of the same expression many times, then you might want to map them onto keys in your
<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>
3+1 Off course! The
"=register. :-/ Feb 25, 2011 at 7:42
3to get the value of a vim variable (for example, sessionoptions):
<C-R>=&sessionoptions-- it even does wildmode tab-completion! Oct 25, 2012 at 18:22
6:put =strftime('%c')<C-M> Aug 13, 2015 at 19:23
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.– jdhaoApr 24, 2019 at 8:51
For some reason, this just doesn't work for me. Any ideas why it wouldn't work?– trusktrDec 28, 2020 at 22:48
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 pastecommand before returning the output and a
set nopasteafter, 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. Jan 5, 2015 at 21:17
set nopasteshouldn't work after
return 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. Apr 23, 2015 at 4:57
Instead of i^R=Exec('ls'), try
:put =Exec('ls'). That should avoid the need to for setpaste.– idbriiApr 26, 2020 at 20:29
These commands will insert the output of
strftime("%c") right where your cursor is:
:exe ":normal i" . strftime("%c")
: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 of
strftime("%c")) to the buffer?– trusktrDec 28, 2020 at 22:47
feedkeys("i"."foo")Dec 29, 2020 at 20:00
: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"))
:call setline(line('.'), getline(line('.')) . " " . strftime("%c"))
depending on whether you want a space inserted before the date or not.
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.
let @o = output syntax sets the register
o to the contents of the variable
output, as explained here: https://stackoverflow.com/a/22738310/1143274
return '' line is so that the default return value of
0 doesn't get inserted to the buffer.
You can use
:put with the expression register
This method allows you to make an alternative command to
:InsertExpr that would insert your expression:
command! -nargs=* InsertExpr put =<args>
Or to insert commands like
command! -nargs=* InsertCmd put =execute('<args>')
(Not sure why I can't get q-args to work.)
:InsertExpr strftime('%c') :InsertCmd ls
This is how I do it. It puts it right after the cursor because it uses
" 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
If you end up mapping it at the end then there is a nicer way.
inoremap <expr> <C-f> strftime('%c')
This is quite general, just substitude your binding for Ctrl-F and your function for