This commit is contained in:
Mathias Schneider
2026-04-01 17:47:07 +02:00
parent a4f69f1555
commit 88853f3a25
2 changed files with 165 additions and 1 deletions
@@ -0,0 +1,146 @@
## Introduction[](https://blog.chaitanyashahare.com/posts/project-wide-find-and-replace-in-neovim/#introduction)
Maintaining an organized and efficient codebase is essential for every developer. Neovim, a powerful text editor, offers a range of tools that can help you make global changes throughout your project with ease.
In this blog post, well explore how to perform a project-wide find and replace using Neovim, Telescope, the Quickfix List, and the `:cdo` command. No complicated jargon, just straightforward guidance to enhance your coding experience.
## Prerequisites[](https://blog.chaitanyashahare.com/posts/project-wide-find-and-replace-in-neovim/#prerequisites)
Before you start, ensure you have the following prerequisites in place:
1. Neovim installed.
2. The Telescope plugin installed.
3. A project directory opened in Neovim.
## Using Telescope for Live Grep[](https://blog.chaitanyashahare.com/posts/project-wide-find-and-replace-in-neovim/#using-telescope-for-live-grep)
### 1. Initiate Telescope[](https://blog.chaitanyashahare.com/posts/project-wide-find-and-replace-in-neovim/#1-initiate-telescope)
In Neovims Normal mode, execute the following command:
```shell
:Telescope live_grep
```
This opens the Telescope live grep prompt, ready for your query.
### 2. Enter Your Search Query[](https://blog.chaitanyashahare.com/posts/project-wide-find-and-replace-in-neovim/#2-enter-your-search-query)
Type your search query. Telescope will display a list of search results throughout your project.
### 3. Open Results in Quickfix List[](https://blog.chaitanyashahare.com/posts/project-wide-find-and-replace-in-neovim/#3-open-results-in-quickfix-list)
After searching for your query, press `Ctrl + q` to open the search results in the Quickfix List.
## Utilizing `:cdo` for Find and Replace[](https://blog.chaitanyashahare.com/posts/project-wide-find-and-replace-in-neovim/#utilizing-cdo-for-find-and-replace)
### 4. Run the `:cdo` Command[](https://blog.chaitanyashahare.com/posts/project-wide-find-and-replace-in-neovim/#4-run-the-cdo-command)
With the Quickfix List open, you can now perform the find and replace operation. Execute the following command:
```shell
:cdo s/query_string/replacement_string/gc
```
- `:cdo` applies a command to each entry in the Quickfix List.
- `s/query_string/replacement_string/gc` is the find and replace command, with `g` for global replacement.
- The `/c` flag provides confirmation before each replacement.
Press Enter to initiate the find and replace with confirmation.
### 5. Save Changes[](https://blog.chaitanyashahare.com/posts/project-wide-find-and-replace-in-neovim/#5-save-changes)
If youre satisfied with the changes and want to save them across all files in your project, you can use the `:wa` command:
```shell
:wa
```
## Conclusion[](https://blog.chaitanyashahare.com/posts/project-wide-find-and-replace-in-neovim/#conclusion)
Performing a project-wide find and replace in Neovim using Telescope, the Quickfix List, and the `:cdo` command is a potent approach that simplifies codebase maintenance. It allows you to make comprehensive changes while retaining full control over the replacement process, with the added `/c` flag providing a confirmation step for each replacement. By incorporating these techniques into your Neovim workflow, youll significantly improve your coding experience and efficiency. Use `:wa` to save your changes across all files and ensure your project is up to date.
# Bsp Zeilen mit Treffern löschen
Es gibt zwei leicht verschiedene Dinge:
1. Zeilen **in den Dateien** löschen
2. Einträge **aus der QuickfixListe** löschen
Ich nehme an, du meinst 1., also die Zeilen in den Dateien entfernen, wo `live_grep` dein Wort gefunden hat. Ich zeige aber beide Varianten.
---
## 1. Zeilen in den Dateien löschen (empfohlen)
Du hast `live_grep` mit z.B. `wits` gemacht und die Treffer in die Quickfix-Liste geschickt (`<C-q>`).
Jetzt willst du **alle Zeilen in den Dateien löschen, die `wits` enthalten**.
Das geht am saubersten mit `:cfdo` + `:global`:
```vim
:cfdo g/wits/d | update
```
Erklärung:
- `cfdo` führe den folgenden Befehl für jede **Datei** aus, die in der Quickfix-Liste vorkommt
- `g/wits/d` in dieser Datei: lösche **alle Zeilen**, die `wits` enthalten
- `| update` speichere die Datei, wenn sie geändert wurde
Damit sind nachher in allen Dateien, die in der Quickfix-Liste sind, sämtliche Zeilen mit `wits` weg.
### Variante ohne hartkodiertes Muster
Wenn du das Suchmuster noch einmal mit `/` gesetzt hast, kannst du es statt `wits` auch aus der letzten Suche nehmen:
```vim
/"dein muster"
:cfdo g//d | update
```
`g//` benutzt dann das aktuelle Suchmuster aus `/`.
---
## 2. Zeilen *aus der Quickfix-Liste* löschen
Falls du **nur die Einträge in der Quickfix-Liste selbst** filtern oder löschen willst (nicht die Dateien):
Quickfix-Fenster öffnen:
```vim
:copen
```
### Einträge mit bestimmtem Muster entfernen
```vim
:cfilter! wits
```
- `:cfilter {pat}` behält nur Einträge, die `{pat}` matchen
- `:cfilter! {pat}` entfernt Einträge, die `{pat}` matchen
Mit `:cfilter! wits` würdest du also alle Quickfix-Einträge wegwerfen, die `wits` enthalten (die Dateien bleiben unverändert).
---
## 3. Warum nicht `:cdo normal! dd`?
Rein technisch könntest du auch:
```vim
:cdo normal! dd
```
Das löscht in jeder Datei die jeweilige Trefferzeile.
Aber: `:cdo` läuft pro **Quickfix-Eintrag**; wenn du Zeilen löschst, können die nachfolgenden Einträge (mit alten Zeilennummern) verrutschen. Deshalb ist `:cfdo g/pattern/d` robuster da wird pro Datei einmal gearbeitet, nicht pro Eintrag.
---
Kurzfassung für dein konkretes Beispiel (`wits` aus den Dateien löschen):
```vim
:cfdo g/wits/d | update
```
+476
View File
@@ -0,0 +1,476 @@
Hier ist ein kompaktes, aber vollständiges **VIM Cheat Sheet** 📝
---
## 🔹 Modi in VIM
|Modus|Bedeutung|Wechsel|
|---|---|---|
|**Normal Mode**|Navigation & Befehle|`Esc`|
|**Insert Mode**|Texteingabe|`i`, `a`, `o`, etc.|
|**Visual Mode**|Text markieren|`v`, `V`, `Ctrl+v`|
|**Command Mode**|Speichern, Beenden, etc.|`:`|
---
## 🔹 Insert Mode Befehle
|Befehl|Wirkung|
|---|---|
|`i`|Vor Cursor einfügen|
|`a`|Nach Cursor einfügen|
|`I`|Am Zeilenanfang einfügen|
|`A`|Am Zeilenende einfügen|
|`o`|Neue Zeile unterhalb|
|`O`|Neue Zeile oberhalb|
---
## 🔹 Navigation (Normal Mode)
### Zeichenweise
```
h ← j ↓ k ↑ l →
```
### Wortweise
```
w nächstes Wort
b vorheriges Wort
e Wortende
```
### Zeilenweise
```
0 Zeilenanfang
^ Erstes Nicht-Leerzeichen
$ Zeilenende
```
### Datei
```
gg Anfang der Datei
G Ende der Datei
:n Gehe zu Zeile n
```
---
## 🔹 Löschen
|Befehl|Wirkung|
|---|---|
|`x`|Zeichen löschen|
|`dd`|Zeile löschen|
|`dw`|Wort löschen|
|`d$`|Bis Zeilenende löschen|
|`d0`|Bis Zeilenanfang löschen|
💡 Kombination: `d` + Bewegung funktioniert immer
(z.B. `d3w` = 3 Wörter löschen)
---
## 🔹 Kopieren & Einfügen
|Befehl|Wirkung|
|---|---|
|`yy`|Zeile kopieren|
|`yw`|Wort kopieren|
|`p`|Nach Cursor einfügen|
|`P`|Vor Cursor einfügen|
#### Register
Vor alle Kopieren oder Einfügen Befehle kann ein `"3` gestellt werden, um ins 3. Register zu schreiben bzw. daraus heraus zu lesen. Z.b. kopiert `"7yw` das Wort ins 7. Register und `"4p` fügt das 4. Register nach dem Curser ein.
💡 Das spezielle Register `+`/`*` ist das System-Clipboard, sehr Praktisch zum Austausch von Text mit anderen Programmen
Alle Register ansehen: `:reg`
💡 Das spezielle Register `%` enthält den aktuellen Dateipfad -> aktuelle Dateipfad in System-Clipboard: `:let @+=@%`.
---
## 🔹 Undo / Redo
```
u Undo
Ctrl+r Redo
```
---
## 🔹 Visual Mode
|Befehl|Wirkung|
|---|---|
|`v`|Zeichenweise markieren|
|`V`|Ganze Zeile markieren|
|`Ctrl+v`|Block markieren|
Nach Markierung:
```
d löschen
y kopieren
> einrücken
< ausrücken
```
---
## 🔹 Suchen & Ersetzen
```
/text Vorwärts suchen
?text Rückwärts suchen
n Nächstes Ergebnis
N Vorheriges Ergebnis
```
Ersetzen:
```
:%s/alt/neu/g Ganze Datei
:s/alt/neu/g Aktuelle Zeile
:%s/alt/neu/gc Mit Bestätigung
```
Nutze "echtes" RegEx ("very magic"):
```
/\v...
```
zB
```
/\vab?c
```
findet `abc` und `ac` . Das würde mit herkömmlicher Vim RegEx nicht funktionieren
Suchen und ersetzen
```
:%s/\vfoo (ab?c)(bar)/bas \1 \2/
```
---
## 🔹 Speichern & Beenden
```
:w Speichern
:q Beenden
:wq Speichern & Beenden
:x Speichern & Beenden
:q! Ohne Speichern beenden
```
---
## 🔹 Fenster & Tabs
```
:split Horizontal teilen
:vsplit Vertikal teilen
Ctrl+w w Zwischen Fenstern wechseln
:tabnew Neuer Tab
gt Nächster Tab
gT Vorheriger Tab
```
---
## 🔹 Nützliche Shortcuts
```
. Letzte Aktion wiederholen
>> Zeile einrücken
<< Zeile ausrücken
ciw Wort ändern
cc Zeile ändern
J Zeilen zusammenführen
```
---
## 🔹 Makros
```
qa Aufnahme in Register a starten
q Aufnahme stoppen
@a Makro a ausführen
@@ Letztes Makro wiederholen
```
---
## 🔹 Zahlen-Präfixe (Sehr wichtig!)
Viele Befehle lassen sich multiplizieren:
```
3dd 3 Zeilen löschen
5w 5 Wörter vor
2yy 2 Zeilen kopieren
```
---
# Zeilennummern aus- und anschalten
---
## 🔹 Absolute Zeilennummern
### Einschalten:
```vim
:set number
```
### Ausschalten:
```vim
:set nonumber
```
### Toggle:
```vim
:set number!
```
---
## 🔹 Relative Zeilennummern
### Einschalten:
```vim
:set relativenumber
```
### Ausschalten:
```vim
:set norelativenumber
```
### Toggle:
```vim
:set relativenumber!
```
---
## 🔹 Absolute + Relative kombinieren (Sehr beliebt 🔥)
Viele nutzen diese Kombination:
```vim
:set number relativenumber
```
👉 Ergebnis:
* Aktuelle Zeile = **absolute Nummer**
* Alle anderen Zeilen = **relative Nummern**
Beispiel:
```
8
2
1
10 ← aktuelle Zeile
1
2
3
```
Das ist perfekt für Bewegungen wie:
```
5j
3k
```
---
## 🔹 Dauerhaft aktivieren (.vimrc)
In deiner `~/.vimrc`:
```vim
set number
set relativenumber
```
---
## 🔹 Smart Toggle Mapping (Optional ⭐)
Viele nutzen ein Keybinding:
```vim
nnoremap <leader>n :set number! relativenumber!<CR>
```
Dann kannst du mit:
```
\ n
```
(beim Standard-`leader`) beide gleichzeitig toggeln.
---
# Block Aus- und Einkommentieren
---
# 🔹 1️⃣ Rein mit Vim (ohne Plugin)
## ✅ Ganze Zeilen im Visual Mode kommentieren
### Schritt 1: Block markieren
* `V` → Zeilenweise markieren
* `j / k` → Bereich wählen
### Schritt 2: Kommentarzeichen einfügen
Beispiel für `#`:
```vim
:s/^/# /
```
Im Visual Mode einfach:
```vim
:'<,'>s/^/# /
```
👉 Fügt `# ` am Anfang jeder markierten Zeile ein.
---
## 🔹 Auskommentieren
```vim
:'<,'>s/^# //
```
---
## 🔹 Noch schneller (ohne `:` tippen)
Markieren mit `V`, dann:
```vim
:s/^/# /
```
Vim setzt `'<,'>` automatisch.
---
# 🔹 2️⃣ Noch effizienter: Visual Block Mode (Sehr elegant ⚡)
Perfekt für feste Kommentarzeichen wie `#`, `//`, `--`.
### Schritt 1
```
Ctrl + v
```
### Schritt 2
Mit `j/k` mehrere Zeilen markieren (nur Spalte 0)
### Schritt 3
```
Shift + i
#
Esc
```
💥 Vim fügt das in alle markierten Zeilen ein.
---
## 🔹 Entfernen mit Block Mode
1. `Ctrl + v`
2. Erste 2 Zeichen (`# `) markieren
3. `d`
---
# 🔹 3️⃣ Beste Lösung: Plugin (Empfohlen 🔥)
Wenn du regelmäßig kommentierst → nimm ein Plugin.
Sehr beliebt:
* vim-commentary von Tim Pope
### Installation (mit vim-plug):
```vim
Plug 'tpope/vim-commentary'
```
### Nutzung:
* `gcc` → aktuelle Zeile toggeln
* `gc` (im Visual Mode) → Block toggeln
💎 Vorteil:
* erkennt automatisch Kommentarzeichen je nach Dateityp
* funktioniert mit `//`, `#`, `--`, `/* */`, etc.
---
# 🔹 4️⃣ Absolute Power-User Lösung (Ohne Plugin, aber smart)
In `.vimrc`:
```vim
vnoremap <leader>c :s/^/# /<CR>
vnoremap <leader>u :s/^# //<CR>
```
Dann:
```
\c → kommentieren
\u → auskommentieren
```
---
# 🔥 Meine Empfehlung
| Wenn du... | Lösung |
| ----------------------------- | ----------------- |
| Nur selten kommentierst | Visual Block Mode |
| Viel programmierst | vim-commentary |
| Minimalistisch bleiben willst | eigenes Mapping |
---
# Verschiedenes
- `%`: zur nächsten Klammer
- `TOhtml`: HTML Export
- `:ls`: Buffer anzeigen -> `:b 3` den 3. Buffer öffnen
- `.` : letzte Aktion wiederholen
- `:e path/to/file` öffnet Datei, nur `:e` aktualisiert die geöffnete Datei, `:e!` verwirft dabei alle Änderungen
- `q:` : öffne Befehlsbuffer
- Dort kann man z.B. mit `"+yy` Befehle ins Clipboard kopieren
-