This is not meant to be a how-to-use-vifm; the documentation on the website is pretty detailed, and comes in two slightly different forms.
Think of this as part "review" and part "tips and tricks" from my point of view. It could help you if you were considering switching to vifm, or even if you have already switched but need a more detailed perspective than you've found so far.
(Note that vifmrc
generally means ~/.config/vifm/vifmrc
. Also note that
many parts of my vifmrc have been snarfed from other people, especially from
the author's own vifmrc!)
- features I really like
- things you'll see right away
- basic file operations
- other file operations
- selecting files
- opening files
- previewing files
- mapping common tasks
- finding files
- finding text within files
- external commands
- ouch!
-
:%s/foo/bar
to directly rename files!(2019-11-10: I am ashamed to say I completely forgot about this and only re-discovered it when reviewing my vifmrc for posting!)
-
undo: I don't know if I've been living under a rock, but I've never seen a file manager with undo! Is this common?
That said, after the initial excitement I found I don't make many mistakes anyway (hem hem!) but still, it's nice to know most things are undoable. (And of course there are things that cannot be undone, such as when content is overwritten. Also it's worth remembering that unlike vim, vifm cannot remember undo across sessions, so don't exit if you want to undo!)
-
tmux integration: While
gvim
is fine for local use, nothing beats tmux for remote sessions, and vifm happily supportstmux
(andscreen
); just add the linescreen!
in your vifmrc.Now, when you hit enter to open a file in vim, it creates a new tmux window and runs vim in there. The window closes when you exit the editor. Very, very, cool, especially when you consider that this is something you simply cannot manually work-around if the fm does not support it!
(There are a few exceptions; for instance see opening all the results of a
:grep
in a vim quickfix list, for good reasons, so just be aware of them and watch your tmux statusbar.) -
synchronised registers: For many things that do not require permanent files, I tend to open a temporary directory (see cli-tips.mkd). I sometimes have several tmux windows with short-lived files in them, and occasionally I need to move or copy files between them. Granted, this is rare, but when it happens, it's a real pain and a major slowdown because those temporary pathnames are quite random!
But by using the
syncregs
setting in my vifmrc, all my vifm sessions are automatically synchronised as far as register contents go. This makes it trivial to copy or move files from one session to another. Open up vifm in both places, hityy
on the source files, switch to the other tmux sessions, and hit eitherp
(for copy) orP
(upperase P, for move). Done.I like this so much that my users's vifmrcs have
let &syncregs = $USER
in them. -
custom commands are so much simpler than in my old file manager, I'm adding it here even though this should be a no-brainer for any fm.
Here're 3 examples from my vifmrc:
command! Tar tar cf %c.tar %c command! Tgz tar zcf %c.tgz %c command! Mkcd :mkdir! %a | cd %a
User defined commands are run by the shell, by default. If you want them to be run by vifm, like in the last example above, start with a
:
.(You can look up
%c
,%C
,%a
and all the others in the section on "Command Macros". (Hint: ignore the second column, which has macros starting with%"
; those are for Windows). -
tree view. Run
:tree
, and thenzd
on any directories (such as.git
) you don't want to see, to get a nice overview. You can even use the=
filter within this view to subset things down. -
previewing directories. I like that when you turn on "preview" (
:view
, or whatever letter you map it to), directories show up with the full tree view on the right side. A real time saver when you are exploring a new directory, or when cleaning up / general housekeeping of long forgotten directories. -
previewing directories with a custom command. You cannot imagine, when browsing a git repo, how nice it is to see a "git log" of the file or directory in the preview window. While most fm's will probably allow that for files, I haven't seen one that lets me do this for a directory. (Details later in this document.)
-
custom views (as vifm calls them) allow you to load a filelist generated by a program. I've always struggled with tasks like finding the most recent files, most recently committed files, largest files, or whatever, because I always had to get out of the file manager.
Not anymore! See section on "finding files" later.
A quick note about the "most recently committed files": by itself that's not such a big deal, but, combined with the previous feature ("git log" as preview), it is a good contrast to
gitk
(or:GV
in vim) -- it is a view from the other direction, in a way (files -> commits, as opposed to commits -> files). Time will tell how useful it really is, but I can certainly say that I know of no other file manager that lets me do this at all, leave alone so painlessly and intuitively, and that's the important part here. -
sorting display: whatever field you choose to sort by, that is the field you will see next to the filename!
It has always bothered me that I can sort by inode change time (ctime), but I can't see that same ctime by default, and in some cases not even with a lot of fiddling.
We all know that space is limited, so tying what is displayed next to the name, to what is chosen as the sort field, is just brilliant!
-
marks that get automatically saved. TBH, I suspect many file managers have this; I know my old one did.
-
2-pane file manager, a la midnight commander. You can also make it show just one pane; I do that sometimes when the filenames are too long and I need to see them in full. Note that the other pane is still there, it's just not shown -- if you hit
<Tab>
you can still switch between them.Also, if you are used to Miller Columns, you can also use those, though I have not used them much with vifm.
You can also have tabs, but I've never been much of a tab user, even in vim, so I can't say much about them. I just know that Vifm lets you have tabs in panes, as well as panes in tabs, which should cater to all tastes! (There are some screenshots on the official website.)
If you're used to the file manager always starting in the current directory, instead of the directory you last visited, set the
vifminfo
option in vifmrc to a list of values that does not includesavedirs
(the default includes it). -
To see hidden files, add
set dotfiles
to vifmrc. You can always toggle them off withza
if you wish. -
Symbolic links are a bit harder. The color might help, but to actually see the target the best option is to set a
statusline
containing%T
somewhere. If symlinks are rare, the simplest way is to just hit enter on it and it will take you to the target. (Hit''
to go back).You also can temporarily change the sort to "link target" (hit
:sort<cr>
thenT
); you'll see all the targets on the right side of the pane. -
Basic movements are all fairly similar to vim. I don't expect people who don't like vim to even get this far into this document, so I assume you're fine with that :)
There are probably some subtle differences here and there, reflecting the fact that editing text is not precisely the same as managing files :) but by and large it's all the same.
Example: when you use visual selection, lowercase v and uppercase V both seem to work, which is kinda obvious since the distinction that vim has, does not make sense here).
Another example, searching for files is as you might expect; just use a "/". But the
f
command (which is a character search on the same line, in vi/vim), is a very convenient way to find the next file starting with the letter you type afterf
. This wraps around, so even if you start on a file at the bottom, and look for, say, 'a', it works. (Needless to say,,
and;
also work as they do in vim, with the exception that vim does not wrap around when the last one is found).
-
Most basic operations work as you might expect. For example, to copy files, you might hit
3yy
with the cursor on a file or directory, which will yank that and the next 2 objects. Then you go somewhere else (or hit TAB to go to the other pane) and hitp
to paste them. -
Deleting files comes in two flavours:
dd
to soft delete (moves them to some trash directory), andDD
to permanently delete. The latter, of course, cannot be undone. -
Moving files needs a bit of explanation. When you cut and paste files using
dd
thenp
, it first moves the files to trash when you typedd
, and moves them again to the new destination when you hitp
. If you're not comfortable with that, the correct way to do this is to useyy
, thenP
(uppercase P). That will move the files in one shot.vifm
can do this because it doesn't need to make the same distinction between uppercase and lowercasep
that vim does. -
bulk rename of files, especially if you have a pattern, is very easy. Just select the files, and hit
cw
(or:rename
). Vim opens up with the filenames preloaded; change them how you like and save, and the rename happens. (Cyclic renames are also handled correctly).Even better, if you're able to express the rename as a pattern match and replace, you can use
:s/foo/bar/
. You can also use groups here (for example,:%s/^([0-9])-/0\1-/
will prefix an extra 0 to files whose names start with a single digit and a hyphen. This also takes/i
and/g
options.
chmod
is easy: just select the files and hitcp
to get a menu; fill it in and hit enter. Or type:chmod u+x
or something like that. You can add a-R
or just usechmod!
to get it to work recursively.
-
t
manually selects a file. (I suggestnmap <space> tj
in your vifmrc so that you can just hit<space>
to select a file and move to the next one).You can also select using
:1,10sel
and so on. Or you can use the search function:/foo<cr>
will select all files containing foo. Even better, you can:select /foo|bar|baz/
to get multiple selections in one go. And then you can finetune that selection by using:unselect
to shave a few files off from that selection!And you can combine any and all these methods however you want. (And that's not even talking about visual selection, which I won't talk about.)
-
You can save selections into registers, just like in vim, using for example
"ayy
, and restore the selection later using"ags
(in this example using registera
). And, just like in vim, uppercase register names (A-Z
) accumulate entries, so you can make multiple selections using various criteria, and keep adding them to a register if you wish.
A quick note: %c
is replaced by the name of the file under the cursor, %f
by the names of all the files selected (if any; if not, it is the same as
%c
).
Some samples from my vifmrc:
" view manpages within downloaded software you're considering installing
filetype *.[1-8] man ./%c
" example showing two choices of app to use
filextype *.epub,*.pdf,*.ps {zathura}zathura %f %i &, okular %f %i &,
" you'll notice this one is using %f, because both zathura and okular can
" handle multiple arguments quite fine.
" example showing multiple lines. The text within braces shows up in
" the popup, by the way.
filetype *.tar,*.tar.bz2,*.tbz2,*.tgz,*.tar.gz,*.tar.xz,*.txz
\ {Yaay! Vim!}
\ vim %c,
\ {View contents}
\ tar -tvf %c | less,
\ {Extract to %D}
\ tar -C %D -xf %c | less,
" Notice we're back to %c, because tar cannot handle more than one tar
" file at a time.
Here's how these multiple choices work. If you put the cursor on a PDF and
type :f<space><tab>
('f' is short for 'file'), a list will pop up that
contains your choices, mixed in with several others that the desktop
environment has decided are appropriate apps for that filetype.
As a convenience, you can hit f<space>X<tab>
, where X
is one or more
letter, then the list that shows up will be limited to applications that start
with those letters. (E.g., on a PDF, with the settings above, I can hit f z<cr>
to run zathura.)
Before I get to the mundane stuff, let me get the cool stuff out of the way:
nnoremap l :if &previewprg == '' | set previewprg='git log --color -- %c 2>&1' | view! | else | set previewprg='' | view | endif<cr>
This little beauty shows me the git log output in the other pane once I hit
l
to toggle it on. It's easily one of the biggest wins for me with vifm,
considering how often I review mine or other people's work in a git repo.
I'm sure many file managers can get you this for a file, but vifm allows previews for directories also to have some custom external command, and this covers both (after all, git log works fine on both files and directories).
Coming back to the boring stuff, here are a few samples from my vifmrc. Note
that all of them use %c
, since %f
simply does not make sense in a
preview command (which by definition operates on the file/directory under the
cursor!)
" some really simple ones
fileviewer *.epub pandoc %c -t plain
fileviewer *.tar,*.tar.bz2,*.tbz2,*.tgz,*.tar.gz,*.tar.xz,*.txz tar -tvf %c
fileviewer *.odt,*.doc,*.docx unoconv -f text --stdout %c
fileviewer *.ods,*.xls,*.xlsx unoconv -f csv --stdout %c
" view manpages within downloaded software you're considering installing
fileviewer *.[1-8] man ./%c | col -b
" notice the difference between the corresponding `filetype` setting; that
" one does not pipe to `col -b`
" if all else fails, just let the `highlight` command figure out what type
" of file it is and show it in nice colors. (You may want to change
" "pablo" to something else)
fileviewer *[^/] highlight -O xterm256 --force -s pablo %c
Sadly, this is still a pain, because there are so many terminal emulators, and so much variation between them (and tmux/screen also muck up things a little too!) My solution:
fileviewer *.bmp,*.jpg,*.jpeg,*.png,*.gif,*.xpm,*.tif,*.tiff
\ bgee %c,
The bgee
script, which should be placed somewhere in your PATH, is just
this:
#!/bin/bash
mediainfo "$1"
( ( geeqie --remote "$1" >/dev/null 2>&1 ) & )
Here's what's happening:
-
the mediainfo produces textual output that the preview pane can show. As far as vifm is concerned this is all that is happening.
-
the double fork runs geeqie with a
--remote
option. Now this is where the choice of image viewer makes a difference: you need one that (a) can be controlled remotely by running a command and (b) does not keep changing it's window size depending on the image it is currently displaying.
When the first image comes under the vifm cursor, geeqie opens up. I then resize it and move it to a corner of the screen, and continue using vifm as usual; images simply show up in that window in the corner whenever I come upon one in my vifm browsing. I can tell you this is a lot more predictable and repeatable than all the stupid w3m tricks I had been forced to pull in the past (and which often failed under tmux or screen anyway!)
Just like vim, vifm uses variants of the map
command to customise your usage
of it. Some samples from my vifmrc follow:
" quick way to select all files in the view
nnoremap VV :%select<cr>
" move the cursor in the other window
nnoremap <silent> J <space>j<space>
nnoremap <silent> K <space>k<space>
" shortcut to sort command
nnoremap S :sort<cr>
" toggle preview, and within preview toggle wrap
nnoremap w :view<cr>
nnoremap W :set wrap!<cr>
" grow/shrink window by 4 columns at a time
nnoremap < 4<c-w><
nnoremap > 4<c-w>>
" tag a file and move down to the next one
nmap <space> tj
" cd should be faster than it is :)
nnoremap cd :cd<space>
" make vimdiff as easy as possible, assuming a file of the same name
" exists in the other panel
nnoremap dv :!vimdiff %c %D/%c<CR>
" rename file; I inserts at the beginning, A appends at the end.
nnoremap I cw<c-a>
nnoremap A cw
The following examples are bit more involved.
Simulating ncdu: I came up with the following:
nnoremap ss :%select<CR>ga:set sort=-size<cr>
works great, but the actual size determinations happens in another thread so for large directories it may be best to wait a while and then sort by size again.
Faster deletion: As mentioned earlier, vifm lets you delete files either by moving them to trash, or permanently. By default, both operations require confirmation by typing "y". I prefer permanent deletion, and I also prefer the confirmation to be simpler, say just hitting "enter". To make it a bit harder, I map this to TWO strikes of the Delete key:
nnoremap <delete><delete> :!ls -ald %f; echo -n "remove these files? "; vifm-pause; rm -rf %f<cr>
You'll see that I am reusing a small script that comes with vifm itself to do the pause and wait for the user to hit enter.
vifm comes with the ability to use the find command, but I hate the find
command. (For a proper rant on find
, see the comments in my sf
command!)
Worse, vifm's way of helping you use the find command inserts -name
somewhere, and although there's a way to get around that (see the help for
findprg
), I steer clear.
Luckily, vifm has also a locateprg
option, which is far simpler. So
here's what I do:
set locateprg="find | grep -i %a"
nnoremap // :locate<space>
Now, hitting //
then some word, finds me all files whose path name (relative
to current PWD) contains that word. Vifm shows this in some kind of an output
window.
Here's where the fun starts. Hit b
, and these files will be loaded in the
active pane as a custom view. You can preview those files, delete them,
edit them, whatever. When you're done, type gh
to come back to the regular
view.
I mentioned this up at the top, but here's how you get the largest N, newest N, or most recently committed N, files.
command! xc :set viewcolumns=*{name}..,24{mtime}| zzzInternalXC %a
command! xm :set viewcolumns=*{name}..,24{mtime}| zzzInternalXM %a
command! xs :set viewcolumns=*{name}..,8{size}| zzzInternalXS %a
command! zzzInternalXC git log --name-only --format=%%n -- %d| CDUP=`git rev-parse --show-cdup` perl -lne 'print if /./ and s(^)($ENV{CDUP}) and -f and not $seen{$_}++' | head -%a %U
command! zzzInternalXM find -type f -print0 | xargs -0 ls -tr | tail -%a | tac %U
command! zzzInternalXS find -type f -print0 | xargs -0 ls -Sr | tail -%a | tac %U
" the 'zzz' is so they will show up last when I hit ':<Tab>'
" also, notice the %% in the format paramater in zzzInternalXC
You run this by typing :xc 10
to get the 10 most recently committed files (c
for 'commit'), and they will be loaded in a custom view. Similarly s is
for size and m is for mtime.
The %a
is replaced by the 10 or 20 or whatever you supplied.
However, the %U
is what makes all this work: it basically takes the
command output and creates a "custom view" out of it! (I use %U
instead of
%u
because I don't want vifm to needlessly sort it on some other key, when
it's already sorted!)
(Due to an odd quirk of the tail
command being quite happy to be run as
tail -
, without a number, you can also say :xc
etc., and it is effectively
treated as :xc 10
).
Speaking for myself, I don't use any IDE, and vim has always been sufficient for my needs. A few plugins (like fugitive and gv), a couple of little functions and some maps, and it does a great job meeting the needs of "explore a new project's code" that I have.
As such, this part of vifm is not that exciting for me, but just for completeness I will describe it.
Using vifm's built-in grep
command can be as simple as :grep pattern
, or,
if you wish, you can make it a bit more complex:
:grep -i -e pattern_1 -e pattern_2
(You can also use "grep -i -E 'pattern_1|pattern_2'
, but I think separate
-e
patterns looks cleaner).
What this does is open up a result window with all the matches. You can:
-
hit enter on any of the lines to be taken to that line in that file in vim. If you're running in tmux or screen, and you have
screen!
in your vifmrc, this will be opened in a new window.Before you do this, you can use
/pattern_3
to find lines within this result set that containedpattern_3
, if you wish to. They will be highlighted and you can usen
orN
to go travel back and forth between them. This helps to further finetune your search. -
hit
b
and all the files that matched will be loaded into a custom view in vifm. -
hit
v
and all the matches will be loaded into a vim quickfix list. From there it's between you and your mad vim skills!(As mentioned earlier, this is one of those cases where it's very hard to open this quickfix list in a new tmux window, so the current window will be used).
-
:!command
runs the command, and when it is done, comes back to vifm pane (it pauses only if the exit code was non-zero). -
:!!command
runs the command, and pauses for you to hit enter when it is done -
:!command &
runs the command in the background.
-
file filters: I find this tanatlisingly useful, but it is somewhat confusing.
[Update 2019-06-14 -- although I don't see a release tag yet, so I won't use it, looking at the dev repo shows there is nomenclature change happening in this regard. I have hopes that once we get to 0.11 this section can be removed or at least changed substantially]
There are actually 3 kinds of filters. I suggest playing with it, or sticking to one type for now. Just to share my confusion, here's what they are:
-
=foo|bar|baz
, called a "local" filter, shows only files that contain one of those strings in the filename -
:filter foo|bar|baz
show all except those files -
:filter! foo|bar|baz
(note the!
) to show those files, making this the same as the=foo|bar|baz
example, but these two are different filters! -
selecting files however you want and pressing
zf
to filter them out. Even though you're manually choosing what to filter, this is called an "automatic filter". -
there are various zX key maps to apply or remove various filters.
My head hurts! This bit looks as if two differemt people came up with a solution, and both were accepted. Or rather, three in this case. It's not at all clear why you'd need all this complexity.
I'll probably stick to the "=" filter, and if I need more, then I will use the select/unselect/manually select process I described earier, then
:invert s
, thenzf
. A suitable mapping can always be made if this gets frequently used.(Side note: the behaviour of
:filter
can be switched by dropping thef
flag fromcpoptions
, should you wish to.) -