vifm – Dateimanager für das Terminal
Am in Rest | Keine Kommentare »
Tags: linux
Ich liebe Tools für die Kommandozeile und gefühlt gibt es ja aktuell wieder ein kleines Revival der Kommandozeile Dank textbasierter Coding Agents. Heute soll es aber mal nicht um KI gehen, sondern um den Dateimanager vifm.
Mein erster Computer in den frühen 1990er Jahren hatte MS DOS 5.0 als Betriebssystem und verfügte über einen Dateimanager namens DOS Shell. Dieser sah ungefähr so aus (Screenshot entstammt dem Internet Archive):

Das Ding war blöd und unverständlich für mich. Der Norton Commander mit seinen 2 Panels war aus meiner Sicht das wesentlich natürlichere Nutzerpattern, um Dateien von einem Quellverzeichnis in ein Zielverzeichnis zu kopieren.

Es gibt auch gute grafische Umsetzungen wie den Total Commander für Windows.
Unter Linux habe ich die letzten 25 Jahre meist den Midnight Commander genutzt, eine grundsolide Software, die auch heute noch alle Ansprüche erfüllt.

Für meine Arbeit verwende ich ein MacBook und unter MacOS funktioniert der Midnight Commander nicht richtig gut. Er startet langsam und das Mapping von Funktionstasten stimmt auch nicht richtig. Deshalb bin ich auf die Suche nach einer Alternativen gegangen.
Dabei bin ich auf den Dateimanager vifm gestoßen. Das kann man als „vim file manager“ lesen. vifm ist ein klassischer Dateimanager im bekannten 2-Panel-Design, der zur Bedienung aber auf Tastenkombinationen des vim Texteditors setzt.

Hier ein kurzer Überblick der wichtigsten Tastenkombinationen, die ich mir zu merken versuche. Den Cursor verschiebt man über:
- h – nach oben bzw. links
- j – runter
- k – hoch
- l – tiefer bzw. rechts
Eine einzelne Datei löscht man nicht über das gewohnte „F8“, sondern über „dd“. Über diese Tastenkombination löscht man im vim eine Textzeile und wie beim vim kann man die gelöschte Datei an anderer Stelle einfügen. Die Datei wird also nicht sofort gelöscht, sondern ist erst mal virtuell verschwunden und kann über ein „p“ an anderer Stelle wieder eingefügt werden.
Dateien markiert man entweder über den „visuellen“ Modus, in den man per „v“ gelangt. Alternativ kann man „t“ drücken, um eine einzelne Datei zu markieren.
Wie bei vim stellt sich natürlich die Frage, wie man vifm beendet. Die Lösung: „ZZ“
Hier noch ein paar wichtige Tastenkombinationen:
- „za“ – versteckte Dateien anzeigen (aka Folding)
- „cp“ – kleiner Hilfsdialog, um Dateirechte zu ändern
- „E“ – eine Datei bearbeiten (etwa im vim)
- „,c“ – die vifm Konfigdatei im vim aufrufen und nach dem Speichern direkt anwenden
- „s“ – eine Shell im aktuellen Verzeichnis öffnen
- „Ctrl + u“ – Panels vertauschen
- „Ctrl + o“ – im anderen Panel das gleiche Verzeichnis öffnen (aka synchronisieren)
- „:zip“ – alle markierten Dateien und Verzeichnisse packen
Ich habe mir noch ein paar wenige Go-to Kommandos definiert, um im aktuellen Panel zum Beispiel den Download Ordner zu öffnen:
- ‚h – Home Verzeichnis öffnen
- ‚d – Download Verzeichnis öffnen
Ich habe nur wenige Änderungen an der mitgelieferten Konfigdatei (~/.config/vifmrc) vorgenommen. Hier mein aktueller Stand:
" vim: filetype=vifm :
"
" Sample configuration file for vifm on OSX (last updated: 11 May, 2025)
"
" You can edit this file by hand. The " character at the beginning of a line
" comments out the line. Blank lines are ignored. The basic format for each
" item is shown with an example.
"
" The purpose of this file
" ========================
" 1. Provide a sensible default configuration out of the box.
" 2. Demonstrate how a typical configuration file might look like.
" 3. Familiarize a user with commonly used features.
" 4. Provide some ideas/settings for various use cases.
"
" How to use this file
" ====================
" - Go through it top to bottom while reading comments.
" - Adjust/remove/comment/uncomment lines as you see fit.
" - Look up :commands or 'options' in the documentation to learn more.
"
" Some settings are set to provide more useful defaults without breaking
" compatibility and others are just a great fit (e.g., some bindings) and are
" almost universally useful, but most lines are provided simply as usage
" examples and can be removed without hesitation. Make configuration specific
" to your needs using this file as a starting point.
" ------------------------------------------------------------------------------
" Main settings
" ------------------------------------------------------------------------------
" Command used to edit files in various contexts. The default is vim.
" If you would like to use another vi clone such as Elvis or Vile
" you will need to change this setting.
"
" Mind that due to `filetype * open` below by default the editor won't be used
" for opening files via l/Enter keys. Comment that line out to change the
" behaviour.
if executable('vim')
set vicmd=vim
elseif executable('nvim')
set vicmd=nvim
elseif executable('elvis')
set vicmd=elvis\ -G\ termcap
elseif executable('vile')
set vicmd=vile
elseif $EDITOR != ''
echo 'Note: using `'.$EDITOR.'` as an editor'
let &vicmd = $EDITOR
endif
" This makes vifm perform file operations on its own instead of relying on
" standard utilities like `cp`. While using `cp` and alike is a more universal
" solution, it's also much slower when processing large amounts of files and
" doesn't support progress measuring.
set syscalls
" Trash Directory
" The default is to move files that are deleted with dd or :d to
" the trash directory. If you change this you will not be able to move
" files by deleting them and then using p to put the file in the new location.
" I recommend not changing this until you are familiar with vifm.
" This probably shouldn't be an option.
set trash
" What should be saved automatically on restarting vifm. Drop "savedirs"
" value if you don't want vifm to remember last visited directories for you.
set vifminfo=dhistory,savedirs,chistory,state,tui,tabs,shistory,ehistory,
\phistory,fhistory,dirstack,registers,bookmarks,bmarks,mchistory
" This is size of all of the many kinds of histories, in particular it's the
" number of last visited directories (not necessarily distinct ones) stored in
" the directory history.
set history=100
" Automatically resolve symbolic links on l or Enter.
set nofollowlinks
" Natural sort of (version) numbers within text.
set sortnumbers
" Maximum number of changes that can be undone.
set undolevels=100
" Use Vim's format of help file (has highlighting and "hyperlinks").
" If you would rather use a plain text help file set novimhelp.
set vimhelp
" If you would like to run an executable file when you
" press Enter, l or Right Arrow, set this.
set norunexec
" Format for displaying time in file list. For example:
" TIME_STAMP_FORMAT=%m/%d-%H:%M
" See man date or man strftime for details.
set timefmt='%Y/%m/%d %H:%M'
" Show list of matches on tab completion in command-line mode
set wildmenu
" Display completions in a form of popup with descriptions of the matches
set wildstyle=popup
" Display suggestions in normal, visual and view modes for keys, marks and
" registers (at most 5 files). In other view, when available.
set suggestoptions=normal,visual,view,otherpane,keys,marks,registers
" Ignore case in search patterns unless it contains at least one uppercase
" letter
set ignorecase
set smartcase
" Don't select search matches automatically
set nohlsearch
" Use increment searching (search while typing)
set incsearch
" Try to leave some space from cursor to upper/lower border in lists
set scrolloff=4
" Don't do too many requests to slow file systems
set slowfs=curlftpfs
" Set custom status line look
" set statusline=" Hint: %z%= %A %10u:%-7g %15s %20d "
set statusline="%A | %E | %d%="
" Suppress "Permission denied" errors using syntax specific to GNU find
if system("find --version | grep -c 'GNU findutils'") != 0
set findprg='find %s %a -print , -type d \( ! -readable -o ! -executable \) -prune'
endif
" Add -s to the default value to suppress "Permission denied" errors
set grepprg="grep -n -H -I -r -s %i %a %s"
" List of color schemes to try (picks the first one supported by the terminal)
colorscheme semidarkdesert Default-256 Default
" ------------------------------------------------------------------------------
" Bookmarks
" ------------------------------------------------------------------------------
" :mark mark /full/directory/path [filename]
mark d ~/Downloads/
mark h ~/
" ------------------------------------------------------------------------------
" Commands
" ------------------------------------------------------------------------------
" :com[mand][!] command_name action
"
" These are some of the macros that can be used in the action part:
" %a for user arguments
" %c for current file under the cursor
" %C for current file under the cursor of inactive pane
" %f for selected file(s)
" %F for selected file(s) of inactive pane
" %b is the same as %f %F
" %d for current directory name
" %D for current directory name of inactive pane
" %r{x} for list of files in register {x}
" %m runs the command in a menu window
" %u uses command's output to build a file list
" see `:help vifm-macros` and `:help vifm-filename-modifiers` for more
" command! df df -h %m 2> /dev/null
command! diff vim -d %f %F
command! zip zip -r %c.zip %f
command! run !! ./%f
" command! make !!make %a
command! mkcd :mkdir %a | cd %a
command! reload :write | restart full
" ------------------------------------------------------------------------------
" File handlers and previewers
" ------------------------------------------------------------------------------
" Setting up handlers that are considered in all environments:
" filetype {pattern1,pattern2} program1,{Optional description}program2
"
" Setting up handlers that are considered only in a graphical environment:
" filextype {pattern} graphical-program %c
"
" Setting up previewers:
" fileviewer {pattern1,pattern2} console-viewer1,console-viewer2
"
" ORDER MATTERS! Both handlers and previewers are considered in the order of
" their definition, therefore they should be defined from most to least
" specific. In particular, catch-all patterns like `*`, `*/`, `.*`, `*.*`
" should be defined after all others.
"
" All entries matching a particular file are considered in order until an
" existing command is found. Other entries are accessible via :file command
" for handlers or via `a` and `A` keys for previewers in view mode.
"
" The ordering can be checked at run-time by running
" :filetype/:filextype/:fileviewer with a file name as the only argument.
" This displays a menu of defined entries annotated with availability of
" commands.
"
" More on syntax and usage:
" - macros like %c, %f, %d, etc. may be used in the commands
" - the %a macro is ignored
" - to insert a literal % use %%
" - spaces in an app name must be escaped, for example:
" + QuickTime\ Player.app
" + "c:/Program Files (x86)/app/app.exe"
" For automated FUSE mounts, you must register an extension with :file[x]type
" in one of the following formats:
"
" :filetype patterns FUSE_MOUNT|mount_cmd %SOURCE_FILE %DESTINATION_DIR
"
" %SOURCE_FILE and %DESTINATION_DIR are filled in at runtime.
"
" Example:
:filetype *.zip,*.[jwe]ar FUSE_MOUNT|fuse-zip %SOURCE_FILE %DESTINATION_DIR
"
" :filetype patterns FUSE_MOUNT2|mount_cmd %PARAM %DESTINATION_DIR
"
" %PARAM and %DESTINATION_DIR are filled in at runtime.
"
" Example:
" :filetype *.ssh FUSE_MOUNT2|sshfs %PARAM %DESTINATION_DIR
"
" %PARAM value is the first line of the matched file, example: root@127.0.0.1:/
"
" You can also add %CLEAR if you want to clear screen before running FUSE
" program. There is also %FOREGROUND, which is useful for entering passwords.
" Pdf
filetype {*.pdf},<application/pdf>
\ {Open in Preview}
\ open -a Preview.app,
\ {Open in Skim}
\ open -a Skim.app,
fileviewer {*.pdf},<application/pdf> pdftotext -nopgbrk %c -
" PostScript
filetype {*.ps,*.eps,*.ps.gz},<application/postscript> open -a Preview.app
" Djvu
filetype {*.djvu},<image/vnd.djvu> open -a MacDjView.app
" Audio
filetype {*.wav,*.mp3,*.flac,*.m4a,*.wma,*.ape,*.ac3,*.og[agx],*.spx,*.opus,
\*.aac,*.mpga},
\<audio/*>
\ {Open in Music}
\ open -a Music.app,
\ {Open in QuickTime Player}
\ open -a QuickTime\ Player.app,
\ {Open in IINA}
\ open -a IINA.app,
fileviewer {*.wav,*.mp3,*.flac,*.m4a,*.wma,*.ape,*.ac3,*.og[agx],*.spx,*.opus,
\*.aac,*.mpga},
\<audio/*>
\ ffprobe -hide_banner -pretty %c 2>&1
" Video
filetype {*.avi,*.mp4,*.wmv,*.dat,*.3gp,*.ogv,*.mkv,*.mpg,*.mpeg,*.vob,
\*.fl[icv],*.m2v,*.mov,*.webm,*.mts,*.m4v,*.r[am],*.qt,*.divx,
\*.as[fx],*.unknown_video},
\<video/*>
\ {Open in QuickTime Player}
\ open -a QuickTime\ Player.app,
\ {Open in IINA}
\ open -a IINA.app,
\ {Open in VLC}
\ open -a VLC.app,
fileviewer {*.avi,*.mp4,*.wmv,*.dat,*.3gp,*.ogv,*.mkv,*.mpg,*.mpeg,*.vob,
\*.fl[icv],*.m2v,*.mov,*.webm,*.mts,*.m4v,*.r[am],*.qt,*.divx,
\*.as[fx],*.unknown_video},
\<video/*>
\ ffprobe -hide_banner -pretty %c 2>&1
" Web
filetype {*.xhtml,*.html,*.htm},<text/html>
\ {Open in Safari}
\ open -a Safari.app,
\ {Open in Firefox}
\ open -a Firefox.app,
\ {Open in Chrome}
\ open -a Google\ Chrome.app,
\ {Open in vim}
\ vim,
fileviewer {*.xhtml,*.html,*.htm},<text/html> w3m -dump -T text/html
" Object
filetype {*.o},<application/x-object> nm %f | less
" Man page
filetype {*.[1-8]},<text/troff> man ./%c
fileviewer {*.[1-8]},<text/troff> man ./%c | col -b
" Image
filetype {*.bmp,*.jpg,*.jpeg,*.png,*.gif,*.xpm},<image/*>
\ open -a Preview.app,
fileviewer {*.bmp,*.jpg,*.jpeg,*.png,*.gif,*.xpm},<image/*>
\ identify %f
" MD5
filetype *.md5
\ {Check MD5 hash sum}
\ md5sum -c %f %S,
" SHA1
filetype *.sha1
\ {Check SHA1 hash sum}
\ shasum -c %f %S,
" SHA256
filetype *.sha256
\ {Check SHA256 hash sum}
\ shasum -a 256 -c %f %S,
" SHA512
filetype *.sha512
\ {Check SHA512 hash sum}
\ shasum -a 512 -c %f %S,
" Torrent
filetype {*.torrent},<application/x-bittorrent> open -a Transmission.app
fileviewer {*.torrent},<application/x-bittorrent>
\ dumptorrent -v %c,
\ transmission-show %c
" Extract zip files
filetype {*.zip},<application/zip,application/java-archive>
\ mkdir %f:r && tar -vxf %f --directory %f:r
fileviewer {*.zip,*.jar,*.war,*.ear},
\<application/zip,application/java-archive>
\ tar -tf %f
" Extract tar archives
filetype {*.tar,*.tar.bz2,*.tbz2,*.tgz,*.tar.gz,*.tar.xz,*.txz,*.tar.zst,
\*.tzst},
\<application/x-tar>
\ tar -vxf %f
fileviewer {*.tar,*.tar.bz2,*.tbz2,*.tgz,*.tar.gz,*.tar.xz,*.txz,*.tar.zst,
\*.tzst},
\<application/x-tar>
\ tar -tf %f
" Extract .bz2 archives
filetype *.bz2 bzip2 -d %f
" Extract .gz files
filetype *.gz gunzip %f
" Extract rar files
filetype *.rar unrar x -y -c- -ad %f %s
fileviewer *.rar unrar lb %c
" Mount .dmg archives
filetype *.dmg open
" Mount disk .img
filetype *.img open
" Open .pkg binaries
filetype *.pkg open
" Office files
filetype {*.odt,*.doc,*.docx,*.xls,*.xlsx,*.odp,*.pptx,*.ppt},
\<application/vnd.openxmlformats-officedocument.*,
\application/msword,
\application/vnd.ms-excel>
\ open -a LibreOffice.app
fileviewer {*.doc},<application/msword> antiword -
fileviewer {*.docx},
\<application/
\vnd.openxmlformats-officedocument.wordprocessingml.document>
\ docx2txt.pl %f -
" Syntax highlighting in preview
"
" Explicitly set highlight type for some extensions
"
" 256-color terminal
" fileviewer *.[ch],*.[ch]pp highlight -O xterm256 -s dante --syntax c %c
" fileviewer Makefile,Makefile.* highlight -O xterm256 -s dante --syntax make %c
"
" 16-color terminal
" fileviewer *.c,*.h highlight -O ansi -s dante %c
"
" Or leave it for automatic detection
" fileviewer *[^/] pygmentize -O style=monokai -f console256 -g
" Displaying pictures in terminal
" fileviewer *.jpg,*.png shellpic %c
" Open all other files with default system programs (you can also remove all
" :file[x]type commands above to ensure they don't interfere with system-wide
" settings). Use of the line below results in ignoring 'vi[x]cmd' option for
" unknown file types on l/Enter keys.
filetype * open
" ------------------------------------------------------------------------------
" Sample keyboard mappings
" ------------------------------------------------------------------------------
" Start shell in current directory
nnoremap s :shell<cr>
" Display sorting dialog
nnoremap S :sort<cr>
" Toggle visibility of preview window
nnoremap w :view<cr>
vnoremap w :view<cr>gv
" Open file in new MacVim tab
" nnoremap o :!mvim --remote-tab-silent %f<cr>
" Open file in new MacVim window
" nnoremap O :!mvim %f<cr>
" Open file in the background using its default program
nnoremap gb :!open -g %f<cr>
" Yank current directory path into the clipboard
nnoremap yd :!printf %d | pbcopy<cr>
" Yank current file path into the clipboard (escape spaces)
nnoremap yf :!printf %f:p:gs? ?\\ ? | pbcopy<cr>
" View preview in Quick Look
nnoremap <space> :!qlmanage -p %f > /dev/null 2>&1<cr>
" Mappings for faster renaming
nnoremap I cw<c-a>
nnoremap cc cw<c-u>
nnoremap A cw
" As above, but without the file extension
" nnoremap I cW<c-a>
" nnoremap cc cW<c-u>
" nnoremap A cW
nnoremap E :edit<cr>
" Open editor to edit vifmrc and apply settings after returning to vifm
nnoremap ,c :write | edit $MYVIFMRC | restart full<cr>
" Open MacVim to edit vifmrc
" nnoremap ,C :!mvim --remote-tab-silent $MYVIFMRC &<cr>
" Toggle wrap setting on ,w key
nnoremap ,w :set wrap!<cr>
" Example of standard two-panel file managers mappings
nnoremap <f3> :!less %f<cr>
nnoremap <f4> :edit<cr>
nnoremap <f5> :copy<cr>
nnoremap <f6> :move<cr>
nnoremap <f7> :mkdir<space>
nnoremap <f8> :delete<cr>
" Midnight commander alike mappings
" Open current directory in the other pane
nnoremap <c-o> :sync<cr>
" Open directory under cursor in the other pane
" nnoremap <c-o> :sync %c<cr>
" Swap panes (uncomment if you don't need builtin behaviour of Ctrl-U)
nnoremap <c-u> <c-w>x
" ------------------------------------------------------------------------------
" Panel configuration examples
" ------------------------------------------------------------------------------
" Customize view columns a bit (enable ellipsis for truncated file names)
" set viewcolumns=-{name}..,6{}.
" Show vertical border
" set fillchars=vborder:│
" Filter-out build artifacts and temporary files
" filter! {*.lo,*.o,*.d,*.class,*.pyc,*.pyo,.*~}
" ------------------------------------------------------------------------------
" Various customization examples
" ------------------------------------------------------------------------------
" Use ag (the silver searcher) instead of grep
" set grepprg='ag --line-numbers %i %a %s'
" Add additional place to look for executables
" let $PATH = $HOME.'/bin/fuse:'.$PATH
" Disable particular shortcut
" nnoremap <left> <nop>
" Export IPC name of current instance as environment variable and use it to
" communicate with the instance later.
"
" It can be used in some shell script that gets run from inside vifm, for
" example, like this:
" vifm --server-name "$VIFM_SERVER_NAME" --remote +"cd '$PWD'"
"
" let $VIFM_SERVER_NAME = v:servername
" Activate screen/tmux support
" screen!
" ------------------------------------------------------------------------------
" Icon decorations example
" ------------------------------------------------------------------------------
" https://github.com/cirala/vifm_devicons
Code-Sprache: HTML, XML (xml)
Mal schauen, ob ich mir die ganzen Tastenkombinationen merken kann. vifm ist auf alle Fälle eine riesige Verbesserung gegenüber dem MacOS Finder und Sven wäre bestimmt stolz auf mich, dass ich doch noch mal ein neues Texttool entdeckt habe :-)