Vim Tips Wiki
(start cleanup)
(some more updates)
Line 1: Line 1:
{{delete|This proposed tip may be deleted, see [[#Proposed deletion|below]].}}
 
 
{{TipProposed
 
{{TipProposed
 
|id=0
 
|id=0
Line 9: Line 8:
 
|version=7.0
 
|version=7.0
 
|subpage=/201002
 
|subpage=/201002
|category1=
+
|category1=Usage
 
|category2=
 
|category2=
 
}}
 
}}
Line 19: Line 18:
   
 
==Using the {{help|prefix=no|:read!}} command==
 
==Using the {{help|prefix=no|:read!}} command==
  +
Reading an external command directly into the current buffer is very easy. Just use the {{help|prefix=no|:read}} command, but instead of giving it a file name to read in, give it the command-line to execute. For example,
*section 1: using {{tt|:r !}} to get the output in the buffer
 
  +
  +
<pre>
 
:read !date
  +
</pre>
  +
  +
will insert the current date on a new line below the current line on most Unix-like systems (on Windows, use <tt>!date /t</tt> instead).
  +
  +
You can specify a specific line number to place the new text below, e.g. to put it at the very top of the buffer:
  +
  +
<pre>
  +
:0read !date
  +
</pre>
   
 
==Using system()==
 
==Using system()==
   
  +
If you don't want to get the command output on a line all by itself, or if you don't want to insert it into a buffer at all, you can use the {{help|prefix=no|system()}} function. For example, to put the current date into a variable named curdate, which you can then use inside a script, use:
''do we need a simpler example here?''
 
  +
  +
<pre>
  +
:let curdate=system('date')
  +
</pre>
   
The sample function shown below appends the output of the command (if successfully executed) to the current line. As mentioned before, using {{help|prefix=no|strftime()}} is a better option for capturing timestamps, but the script below is a relatively simple example which demonstrates three important concepts:
+
system() is probably the most flexible method, it allows complex scripting around the command output, possibly including parsing before any output. For example, the sample function shown below appends the output of the command (if successfully executed) to the end of the current line. As mentioned before, using {{help|prefix=no|strftime()}} is a better option for capturing timestamps, but the script below is a relatively simple example which demonstrates three important concepts:
   
 
# Using {{help|prefix=no|system()}} to gain access to external command output in a script
 
# Using {{help|prefix=no|system()}} to gain access to external command output in a script
Line 53: Line 68:
 
''need useful example here''
 
''need useful example here''
   
==See also==
+
==Using backticks==
  +
Above it is mentioned that using <tt>system()</tt> is ''like'' using backtick expansion in many shells. It should be noted that Vim actually does support real backticks in some situations. See {{help|backtick-expansion}} for details. This means you can do things like:
*[[VimTip467|467 Vim windows displaying output inside vim window]]
 
*[[VimTip1599|1599 Display output of shell commands in new window]]
 
   
==Comments==
 
How about
 
 
<pre>
 
<pre>
  +
:new `date`
:redir => myvariable
 
:!date
 
:redir END
 
:echo myvariable
 
 
</pre>
 
</pre>
   
  +
to open a new buffer with a name matching the current date. This even works on Windows! The :help does not make it clear, but this works using the cmd.exe shell:
Simply
 
  +
 
<pre>
 
<pre>
:r !date
+
:new `date /t`
 
</pre>
 
</pre>
  +
----
 
  +
This also provides a way to use Vim expressions where expressions are not normally allowed. For example, rather than using:
  +
  +
<pre>
  +
:exe 'e' filename_in_var
  +
</pre>
  +
  +
you can use:
  +
  +
<pre>
  +
:e `=filename_in_var`
  +
</pre>
  +
  +
==See also==
 
*[[VimTip467|467 Vim windows displaying output inside vim window]]
 
*[[VimTip1599|1599 Display output of shell commands in new window]]
  +
 
==Comments==
  +
 
If you want capture output to new unnamed buffer and
 
If you want capture output to new unnamed buffer and
 
<pre>
 
<pre>
Line 87: Line 115:
 
----
 
----
 
I have tweaked the lead and added a 'see also', but I am not at all sure this tip should be retained. The script handles <tt>date</tt> but nothing else (and as the introduction says, <tt>strftime()</tt> is a better way to handle dates). I might merge this to one of the 'see also' tips (mainly by keeping the introduction and the <tt>:redir</tt> comment). The <tt>setline()</tt> trick in the above script is nice, but it seems a rather unusual requirement that you would want to append output to the current line. [[User:JohnBeckett|JohnBeckett]] 05:15, May 18, 2010 (UTC)
 
I have tweaked the lead and added a 'see also', but I am not at all sure this tip should be retained. The script handles <tt>date</tt> but nothing else (and as the introduction says, <tt>strftime()</tt> is a better way to handle dates). I might merge this to one of the 'see also' tips (mainly by keeping the introduction and the <tt>:redir</tt> comment). The <tt>setline()</tt> trick in the above script is nice, but it seems a rather unusual requirement that you would want to append output to the current line. [[User:JohnBeckett|JohnBeckett]] 05:15, May 18, 2010 (UTC)
 
----
 
Note, backtick expansion IS supported in Vim in some situations. See {{help|backtick-expansion}} and <tt>:help `=</tt> just below. --[[User:Fritzophrenic|Fritzophrenic]] 19:08, November 29, 2010 (UTC)
 
 
===Proposed deletion===
 
Please see [[Vim Tips Wiki:New tips/201002#Append output of an external command|201002]] for a proposal that this tip be deleted (discussion should occur on the 201002 page). I have added the delete tag and this note for anyone watching this page. [[User:JohnBeckett|JohnBeckett]] 07:47, July 4, 2010 (UTC)
 

Revision as of 03:09, 23 March 2011

Proposed tip Please edit this page to improve it, or add your comments below (do not use the discussion page).

Please use new tips to discuss whether this page should be a permanent tip, or whether it should be merged to an existing tip.
created February 9, 2010 · complexity basic · author Perlsomian · version 7.0

For many reasons, a user may want to use the output from an external "shell" command within Vim. Vim does have many useful functions which can be used more readily to replace many shell commands, such as strftime() or glob(), but sometimes only the shell command will do. (See :help function-list for a list of Vim's built-in functions).

Some techniques are presented below showing how to capture the results from running an external command. The results can be inserted into to the current buffer with a :read command, can replace lines in a buffer via a filter command, or Vim's system() function can be used similarly to the backquote syntax (aka backtick) that many Unix shells provide to capture command output, which you can then use in a script or expression-register (:help quote=) to append to a current line or parse in some way.

The following examples capture the output of the shell's date command. This is just an example: using Vim's strftime() function would be a better choice if you need the date or time in a script.

Using the :read! command

Reading an external command directly into the current buffer is very easy. Just use the :read command, but instead of giving it a file name to read in, give it the command-line to execute. For example,

:read !date

will insert the current date on a new line below the current line on most Unix-like systems (on Windows, use !date /t instead).

You can specify a specific line number to place the new text below, e.g. to put it at the very top of the buffer:

:0read !date

Using system()

If you don't want to get the command output on a line all by itself, or if you don't want to insert it into a buffer at all, you can use the system() function. For example, to put the current date into a variable named curdate, which you can then use inside a script, use:

:let curdate=system('date')

system() is probably the most flexible method, it allows complex scripting around the command output, possibly including parsing before any output. For example, the sample function shown below appends the output of the command (if successfully executed) to the end of the current line. As mentioned before, using strftime() is a better option for capturing timestamps, but the script below is a relatively simple example which demonstrates three important concepts:

  1. Using system() to gain access to external command output in a script
  2. If you use arguments to your external command, you will probably need to pass them through shellescape() first, or your script could easily break
  3. Using setline() is a good way to change text in a script without moving the cursor. Note this also works for built-in functions.
nnoremap <F8> :call GetDate('')<CR>
function! GetDate(format)
  let utilpath = '/bin/'
  let fmt = a:format ? a:format : '+%A m%m/d%d/y%Y %R UTC'
  let SPECIALCHARS = 1
  let TemporalFormat = shellescape(fmt, SPECIALCHARS)
  let DStamp = substitute(system(utilpath .'date -u '. TemporalFormat)
        \ , '[\]\|[[:cntrl:]]', '', 'g')
  " Append result to current line without moving cursor.
  call setline(line('.'), getline('.') . DStamp)
endfunction

todo: explain why SPECIALCHARS

Using a filter command

:help :range! gives details about using a filter command. This command is used to completely replace one or more lines with the output of an external command using the text currently in the lines as input. See :help filter.

need useful example here

Using backticks

Above it is mentioned that using system() is like using backtick expansion in many shells. It should be noted that Vim actually does support real backticks in some situations. See :help backtick-expansion for details. This means you can do things like:

:new `date`

to open a new buffer with a name matching the current date. This even works on Windows! The :help does not make it clear, but this works using the cmd.exe shell:

:new `date /t`

This also provides a way to use Vim expressions where expressions are not normally allowed. For example, rather than using:

:exe 'e' filename_in_var

you can use:

:e `=filename_in_var`

See also

Comments

If you want capture output to new unnamed buffer and

command! -nargs=* -complete=shellcmd R exe "new | setlocal buftype=nofile bufhidden=hide noswapfile | r !<args>"

" Now you can
:R find | xargs grep vim
" or
:R ls -la
" or whatever
:R mysql -vvt -e'show databases'
Doesn't the :command need to use the -bar flag here so it will see a | as one of its arguments? Without that, I don't think the
:R find | xargs grep vim
example will work. That should also remove the need for the use of :exe. JamesVega 15:52, February 17, 2010 (UTC)

I have tweaked the lead and added a 'see also', but I am not at all sure this tip should be retained. The script handles date but nothing else (and as the introduction says, strftime() is a better way to handle dates). I might merge this to one of the 'see also' tips (mainly by keeping the introduction and the :redir comment). The setline() trick in the above script is nice, but it seems a rather unusual requirement that you would want to append output to the current line. JohnBeckett 05:15, May 18, 2010 (UTC)