Die grundlegenden Datei-Operationen in Vim — Öffnen, Speichern, Einlesen, Neuladen — sind in der Regel die ersten Ex-Befehle, die ein Vim-Nutzer auswendig kennt. Sie sind dabei mehr als die :w/:q-Kombination, die in jedem „Wie verlasse ich Vim?"-Meme auftaucht: hinter :e steckt eine Befehlsfamilie mit Pfad-Modifiern, hinter :w mehrere Varianten für „in andere Datei", „nur bei Änderung" oder „inklusive Backup", und mit :r lassen sich Datei-Inhalte oder Shell-Outputs an die Cursor-Position einfügen. Dazu kommt autoread für Workflows mit externen Tools (Git-Pull, Build-Steps), die Dateien während der Edit-Session ändern. Dieser Artikel deckt alle wichtigen Datei-Operationen ab und führt die Vim-Pfad-Modifier ein, die in vielen späteren Kapiteln wieder auftauchen.
:e — Datei öffnen
Der zentrale Befehl zum Öffnen:
| Befehl | Aktion |
|---|---|
:e foo.txt | öffnet foo.txt im aktuellen Fenster |
:e ./foo.txt | relativ zum aktuellen Arbeitsverzeichnis |
:e ~/.vimrc | mit ~-Expansion zum Home-Verzeichnis |
:e %:h/bar.txt | im selben Verzeichnis wie die aktuelle Datei |
:e | aktuelle Datei neu von Platte laden (nur wenn unmodifiziert) |
:e! | aktuelle Datei neu laden, ungespeicherte Änderungen verwerfen |
:edit foo.txt | Langform von :e |
:e mit Tab-Completion ist im Alltag der häufigste Weg, eine Datei zu öffnen. Wer ein Verzeichnis als Argument übergibt (:e src/), öffnet stattdessen den netrw-Datei-Manager — siehe Artikel netrw.
Der vielleicht eleganteste Trick ist die Verwendung von Pfad-Modifiern: % ist Vims Token für „aktueller Dateiname", und mit Suffixen lässt es sich filtern:
| Modifier | Bedeutung | Beispiel |
|---|---|---|
% | voller Pfad der aktuellen Datei | src/controllers/auth.go |
%:t | nur der Datei-Name (tail) | auth.go |
%:h | nur das Verzeichnis (head) | src/controllers |
%:r | ohne Extension (root) | src/controllers/auth |
%:e | nur die Extension | go |
%:p | absoluter Pfad | /home/user/proj/src/... |
%:p:h | absolutes Verzeichnis | /home/user/proj/src/controllers |
In Kombination mit :e ergibt das Befehle wie:
" In src/controllers/auth.go arbeitend...
:e %:h/profile.go " öffnet src/controllers/profile.go
:e %:r_test.go " öffnet src/controllers/auth_test.go
:e %:p:h/../README.md " absolutes Verzeichnis plus relativDiese Schreibweise spart enorm Tipparbeit in größeren Codebases — kein vollständiger Pfad nötig, der aktuelle Kontext liefert die meisten Bestandteile.
:w — Datei speichern
:w (kurz für :write) schreibt den aktuellen Buffer auf die Platte. Die wichtigsten Varianten:
| Befehl | Aktion |
|---|---|
:w | aktuelle Datei speichern |
:w neue.txt | Buffer in eine andere Datei schreiben — Buffer bleibt auf der alten |
:saveas neue.txt | Buffer in neue Datei speichern — Buffer-Name wird umgesetzt |
:w! | Schreibvorgang erzwingen (z. B. bei read-only) |
:wa | alle modifizierten Buffer speichern |
:update / :up | nur speichern, falls modifiziert (anders als :w, das immer schreibt) |
:x / ZZ | speichern und Vim beenden |
ZQ | beenden ohne speichern (wie :q!) |
Ein wichtiger Unterschied: :w neue.txt kopiert den Buffer-Inhalt in eine neue Datei, aber der Buffer bleibt mit seinem alten Namen verbunden. Wer eigentlich „Speichern unter" meint — also den Buffer-Namen wechseln und ab jetzt in die neue Datei schreiben — nutzt :saveas.
:update (oder kurz :up) ist eine oft übersehene Variante, die im Alltag besser passt als :w: sie schreibt nur, wenn der Buffer modifiziert ist. :w schreibt immer und aktualisiert dabei die mtime der Datei, was Build-Tools, File-Watcher oder Auto-Reload-Mechanismen unnötig triggern kann. :update ist die schonendere Variante.
" Bequemes Mapping für Speichern
" :update statt :w schont mtime — Build-Tools triggern nicht unnötig.
nnoremap <silent> <leader>w :update<CR>ZZ und ZQ sind die Tasten-Kombinationen ohne Doppelpunkt — schnellste Variante für „speichern und raus" bzw. „weg ohne speichern". Beide sind im Alltag häufig gewählt, weil sie nur zwei Tasten brauchen.
:r — Inhalte einlesen
:r (kurz für :read) fügt Inhalt an die Cursor-Position ein. Drei Quellen sind möglich:
| Befehl | Aktion |
|---|---|
:r foo.txt | Inhalt der Datei foo.txt nach der aktuellen Zeile einfügen |
:0r foo.txt | am Buffer-Anfang einfügen |
:$r foo.txt | am Buffer-Ende einfügen |
:r !date | Output eines Shell-Befehls einfügen |
:r !curl -s ... | Output eines HTTP-Aufrufs |
:r !find . -name '*.go' | Liste aller Go-Dateien als Buffer-Inhalt |
:r !command ist besonders nützlich für strukturierte Daten-Einsätze:
:r !date " 2026-05-17 14:23:11
:r !curl -s https://api.ipify.org " externe IP
:r !ls *.md " Markdown-Datei-Liste
:r !cat ~/.gitconfig " einfache Datei-Inklusion
:r !sed 's/old/new/g' input.txt " transformierte DateiMit Range vor :r lässt sich präzise einfügen:
:0r license.txt " License-Header an Buffer-Anfang einfügen
:42r snippet.go " an Position nach Zeile 42 einfügen
:$r footer.md " am Buffer-Ende einfügenNeue Dateien erzeugen
Drei Wege, eine neue Datei zu beginnen:
| Befehl | Aktion |
|---|---|
:enew | neuer leerer Buffer [No Name] — Datei-Bindung erst beim Speichern |
:e neue-datei.txt | öffnet die Datei (oder erzeugt sie virtuell, falls nicht vorhanden) |
:tabnew foo.txt | neue Datei in neuem Tab |
:e foo.txt legt die Datei nicht sofort an. Es erzeugt einen Buffer mit dem Namen foo.txt und der Bemerkung [New] in der Statusline. Erst beim ersten :w entsteht die tatsächliche Datei auf der Platte.
:e neue-config.yaml " Buffer existiert, Datei noch nicht
" (tippe Inhalt)
:w " jetzt entsteht die DateiWer in einem noch nicht existierenden Verzeichnis eine Datei anlegen will, hat einen kleinen Stolperstein: Vim erzeugt das Verzeichnis nicht automatisch. :e new/dir/foo.txt öffnet zwar den Buffer, aber :w schlägt fehl mit E212: Can't open file for writing. Lösung:
:!mkdir -p %:h " Verzeichnis des aktuellen Buffers anlegen
:w " jetzt klappt'sEine Mapping- oder Plugin-Variante automatisiert das — z. B. vim-eunuch mit :Move, :Mkdir, :SudoWrite.
:e! und externe Datei-Änderungen
Wenn eine Datei außerhalb von Vim geändert wird — typisch beim Git-Pull, beim Build, beim externen Editor — gibt es zwei Szenarien:
Vim merkt die Änderung von selbst
Mit der Option autoread prüft Vim regelmäßig (bzw. bei bestimmten Events wie Fokuswechsel), ob die Datei auf der Platte sich geändert hat — und lädt sie automatisch neu, sofern der Buffer nicht modifiziert ist:
" Externe Änderungen automatisch übernehmen
set autoread
" Vim prüft autoread nur bei bestimmten Events.
" Mit einem autocmd erzwingen wir die Prüfung bei mehr Gelegenheiten.
autocmd FocusGained,BufEnter,CursorHold,CursorHoldI *
\ if mode() != 'c' | checktime | endif
" Wenn eine Datei sich extern geändert hat — informiere statt zu warnen
autocmd FileChangedShellPost *
\ echohl WarningMsg | echo "File changed on disk. Buffer reloaded."
\ | echohl NoneMit dieser Konfiguration aktualisiert Vim die Anzeige bei jedem Fokuswechsel und Cursor-Stillstand. Praktisch beim Tab-Wechsel im Browser, beim Auto-Format durch externe Tools, beim Git-Pull während des Editierens.
Du willst manuell neu laden
:e ohne Argument lädt die aktuelle Datei neu — funktioniert aber nur, wenn der Buffer unmodifiziert ist. Bei modifiziertem Buffer wirft Vim E37: No write since last change.
Wer die ungespeicherten Änderungen verwerfen will:
:e! " Buffer von Platte neu laden, Änderungen weg:e! ist nicht reversibel — die ungespeicherten Edits sind weg. Sinnvoll, wenn man weiß: „die externe Version ist die richtige".
Read-only und root-Dateien
Vim öffnet manche Dateien standardmäßig im Read-only-Modus:
- Dateien ohne Schreibberechtigung
- Dateien, die mit
view(Synonym fürvim -R) geöffnet wurden - Dateien mit
:set readonlyim Buffer
In Read-only-Buffern darf man editieren — aber :w schlägt fehl. Wer trotzdem speichern will, hat zwei Optionen:
:w! " Schreibvorgang erzwingen
:set noreadonly | :w " Read-only ausschalten, dann speichernFür system-eigene Dateien, die nur mit sudo bearbeitbar sind, gibt es einen Trick — der für Vim-Variante mit +clipboard typisch ist:
:w !sudo tee % > /dev/null
" Erklärung:
" :w !command schickt den Buffer-Inhalt an `command` als stdin
" sudo tee % schreibt mit sudo-Rechten in die aktuelle Datei
" > /dev/null unterdrückt das Tee-Output-EchoDiese Schreibweise ist einprägsam genug, dass sich viele User ein Mapping dafür anlegen — oder das vim-eunuch-Plugin nutzen, das :SudoWrite als Komfort-Variante mitbringt.
Recent Files und Datei-Historie
Vim erinnert sich an zuletzt geöffnete Dateien über zwei Mechanismen:
:oldfiles und <C-O> für :browse oldfiles
:oldfiles zeigt eine durchnummerierte Liste der zuletzt von Vim geöffneten Dateien (Default: 100 Einträge):
:oldfiles
" Ausgabe:
" 1: /home/user/projects/site/index.html
" 2: /home/user/projects/site/style.css
" 3: /home/user/.vimrc
" 4: /home/user/notes/2026-05-17.md
" ...
:browse oldfiles
" Interaktive Auswahl per NummerDie Liste wird in der viminfo-Datei persistiert (siehe nächster Abschnitt) und überdauert Vim-Restarts.
MRU-Plugins
Für eine bessere UX gibt es Plugins:
- vim-mru — klassischer „Most Recently Used"-Picker
- fzf.vim mit
:History— Fuzzy-Picker für die:oldfiles-Liste - vim-startify — Start-Bildschirm mit Recent-Files-Liste
Diese Plugins sind im Alltag deutlich angenehmer als :browse oldfiles. Für die Konfiguration: siehe Plugin-Management.
Die viminfo-Datei
Vims Session-übergreifender Speicher liegt in ~/.viminfo (oder XDG-konform in ~/.local/state/vim/viminfo). Diese Datei speichert:
:oldfiles-Liste (zuletzt geöffnete Dateien)- Cursor-Position pro Datei — Vim öffnet eine Datei am letzten Standort
- Marks A-Z (globale, file-übergreifende Marks)
- Registers und ihre Inhalte
- Such- und Command-History
- Buffer-Liste (optional)
Die Option viminfo konfiguriert, was gespeichert wird:
" Default ist eine gute Basis, aber explizit Setzen schadet nicht.
" ' = Anzahl Dateien mit Mark-Speicherung
" < = max Zeilen pro Register
" s = max Größe pro Register in KB
" h = no highlight beim Re-Open (vermeidet alte Search-Highlights)
set viminfo='1000,<50,s10,hDer Wiedereröffnungs-Effekt mit der gespeicherten Cursor-Position ist einer der unauffälligen Komfort-Gewinne: wer eine große Datei verlässt und tags drauf wieder öffnet, landet exakt an der Stelle, an der er war. Default-aktiv, kein Setup nötig.
Interessantes
`:w` aktualisiert mtime — `:update` nicht (wenn unmodifiziert)
Bei Build-Tools, File-Watchern oder Hot-Reload kann das einen Unterschied machen. Wer Tools nicht unnötig triggern will, mappt sich :update auf das Speicher-Mapping statt :w. Im Alltag fast immer die bessere Wahl.
`:w neue.txt` ist NICHT „Speichern unter"
Der Buffer bleibt mit dem alten Namen verbunden — :w neue.txt ist eine Kopie-Operation. Wer den Buffer-Namen wechseln will, nutzt :saveas neue.txt. Häufige Verwechslung, die zu „warum bearbeite ich plötzlich die alte Datei?"-Momenten führt.
`%` und Verwandte sind auch in Mappings nutzbar
Pfad-Modifier wie %:h, %:r funktionieren überall, wo Vim Dateinamen erwartet — :e, :w, :source, :!command %. In Mappings besonders nützlich: nnoremap <leader>r :!python3 %<CR> startet die aktuelle Datei in Python.
`autoread` allein reicht oft nicht
Vim prüft autoread nur an bestimmten Events — typisch beim Buffer-Wechsel, nicht im Hintergrund. Wer wirklich Live-Reload will, kombiniert autoread mit einem autocmd FocusGained,BufEnter * checktime. Erst dann funktioniert es wie in einem modernen Editor.
`:e!` ist destruktiv — kein Undo zurück
Mit :e! verwirft Vim alle ungespeicherten Änderungen und lädt die Datei von Platte neu. Es gibt kein u, das das rückgängig macht. Im Zweifelsfall vorher :w als Backup oder set undofile für persistent-undo (siehe Abbrechen und Undo).
`:oldfiles` ist persistent über viminfo
Beim Vim-Start ist die :oldfiles-Liste schon gefüllt — sie wurde in der viminfo gespeichert. Wer die Liste leeren will: ~/.viminfo löschen (oder :set viminfo='0 für „keine Datei-Erinnerung").
Weiterführende Ressourcen
Externe Quellen
- Vim Help: editing.txt — alle Datei-Operationen.
- Vim Help: :write — Schreibvarianten.
- Vim Help: filename-modifiers — Pfad-Modifier wie %:h, %:t, %:r.
- Vim Help: autoread — Live-Reload-Option.
- Vim Help: viminfo — die Session-Datei.
- vim-eunuch — Komfort-Plugin für Datei-Operationen (
:Move,:Mkdir,:SudoWrite).