Vifm: run command on each selected file individually

I want a for loop analog for Vifm.

When I don’t select any file, I can type :!echo %f and I see the output of echo with the current file name as the argument.

When I select several files, :!echo %f yields output of echo with all selected filenames joined with spaces as the argument.

What if I want to apply any program (e.g. echo) to each selected file? So

echo file1
echo file2
echo file3

instead of

echo file1 file2 file3

What options do I have?

P.S.: I want the Vifm analog of the following Bash code:

for f in file1 file2 file3; do
  echo $f
Asked By: petRUShka


This will produce the desired output:

:!echo %f | xargs -n 1 echo

Of course you could define a command (e.g. for) for convenient usage:

:com for echo %f | xargs -n 1

Then you can just type:

:for echo
Answered By: dirdi

Option 1: User-defined command

:com loop for f in %f; do %a "$f"; done

Put that in ~/.config/vifm/vifmrc to always have the command set-up.

To apply ls -l to each selected file, issue

:loop ls -l

Two macros were used:

  • %f The properly quoted selected file names.
  • %a Arguments. In our example, ls and -l.

Option 2: Map

:noremap b :!for f in %f; do  "$f"; done<A-B><A-B><Left>

Again, put that in ~/.config/vifm/vifmrc to always have the map set-up.

When you press b in normal or visual modes, the for loop will show up in the command-line, and the cursor will conveniently be positioned just between do and "$f", so you can just type the command you want and press Enter.

The cursor positioning is done by the <A-B><A-B><Left> part: In command-line mode, Alt+B moves the cursor to the beginning of the previous word, and Left (obviously) one space to the left.

Note: Remember to add & to background the command if it takes long to run and you don’t want Vifm to block while it runs.

Answered By: Quasímodo
Categories: Answers Tags: , ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.