In Vim,
:%!ls
executes ls
command and prints its output to the current editable file.
But what do %
and !
mean separately in vim
?
Is it possible execute ls
and not put its output to document?
According to VIM Tutorial:
%
Move cursor to the matching bracket.
Place cursor on {}[]() and type "%".
!
filter through external command
Any UNIX command can be executed from the vi command line by typing an "!" before the UNIX command.
Autowrite can be intentionally avoided by using "!" to avoid the save when switching files.
for more information see Vim Commands Cheat Sheet, and VIM Tutorial
I had this same question and found this in :h cmdline-special
, which was the meaning I was looking for:
% Is replaced with the current file name. *:_%* *c_%*
None of these answers is properly correct. At the beginning of a Vim command line statement, you can specify a range over which to operate. %
is a common range for specifying the whole file, shorthand for 1,$
, i.e. line 1 to end of file. See See :h cmdline-ranges
for more.
In order to understand what is happening we are going to break this in two parts. First, range and then filter.
Range is the way vim uses to signalise where the operation is taken place, as per ':help range' we can have these:
Line numbers may be specified with: :range E14 {address}
{number} an absolute line number
. the current line :.
$ the last line in the file :$
% equal to 1,$ (the entire file) :%
't position of mark t (lowercase) :'
'T position of mark T (uppercase); when the mark is in
another file it cannot be used in a range
/{pattern}[/] the next line where {pattern} matches :/
?{pattern}[?] the previous line where {pattern} matches :?
\/ the next line where the previously used search
pattern matches
\? the previous line where the previously used search
pattern matches
\& the next line where the previously used substitute
pattern matches
Notice '%' will apply the operation for the entire file.
The other part is the filter operation, as per ':help filter', one of ways of filtering is:
:{range}![!]{filter} [!][arg] :range!
Filter {range} lines through the external program
{filter}. Vim replaces the optional bangs with the
latest given command and appends the optional [arg].
Vim saves the output of the filter command in a
temporary file and then reads the file into the buffer
tempfile. Vim uses the 'shellredir' option to
redirect the filter output to the temporary file.
However, if the 'shelltemp' option is off then pipes
are used when possible (on Unix).
Notice the first part of the command is to inform the range.
So, bringing to your case, :%!ls is informing to vim perform the ls command and apply the result to the entire file.
Command mode operation of Vim
:%
select all the contents of the file
:!
filter through external command
:%!ls
does ls | vim -
in Bash Terminal
But :pu!
in this case, !
means current position
Compare :pu
does normal mode p
and :pu!
does normal mode P