Vim-Gewohnheit, KI daneben: Neovim als IDE
Ich habe Urlaub, und damit auch etwas mehr Zeit, um Dinge auszuprobieren. Ganz im Sinne des „Jahrzehnts der Bash" – das habe ich persönlich für mich ausgerufen :D – wollte ich weg von einer IDE wie Code OSS und mal etwas rein textbasiertes testen. Rausgekommen ist, wie ich finde, ein ziemlich cooles Setup mit Neovim: LSP-Support für Go und Bash, dazu eine KI-Integration, die nicht an einen bestimmten Anbieter gebunden ist.
Hauptsächlich habe ich getestet und verschiedene Varianten durchgespielt. Da ich bei Mittwald einen API-Token habe, lief der Test entsprechend darüber – der openai_compatible-Adapter würde aber genauso mit jedem anderen Server funktionieren, der dieselben API-Konventionen einhält. Auch lokale LLM würden gehen, aber auf meinem 2013er ThinkPad teste ich das lieber nicht.
Aus Erfahrung weiß ich: Wenn man den Qwen-Modellen im Kontext auf die Sprünge hilft, liefern sie durchaus passable Ergebnisse – zumindest bei Bash, das kann ich beurteilen. Bei allem anderen bin ich vorsichtig mit einem Urteil, weil ich schlicht nicht tief genug drinstecke, um zu sehen, wo das Modell danebenliegt.
Ganz allgemein: Ich glaube, die Entwicklung bei KI geht genau in diese Richtung. Open-Weight-Modelle werden kleiner und gleichzeitig leistungsfähiger – was vor kurzem noch ein Rechenzentrum brauchte, läuft heute auf brauchbarer Consumer-Hardware. Das ist für mich der eigentlich interessante Trend, spannender als jedes neue Flaggschiff-Modell: weg von "man muss zwingend über die API eines großen Anbieters gehen", hin zu "man kann sich sein Modell selbst hinstellen". Ich gehe davon aus, dass dieser Sprung zum lokalen Betrieb kommt – vielleicht nicht morgen, aber ich rechne fest damit. Und wenn er kommt, ist die Neovim-Config schon vorbereitet.
Warum Neovim
Man sollte immer offen für Neues sein, gleichzeitig darf man sich an eine Bedienung auch einfach gewöhnen, das ist normal und menschlich. Ich komme von Vim und Sway, da ist Neovim irgendwie ein logischer Schritt, glaube ich. Ich bin da ehrlich gesagt auch einfach faul und wollte nicht groß neu lernen. Trotzdem darf das nicht heißen, dass man aufhört zu verstehen. Copy-Paste ohne nachzudenken führt früher oder später zu Problemen. Man sollte zumindest verstehen, was ein Befehl oder eine Funktion tut. Nachvollziehen, was gerade in der eigenen Datei passiert, bevor man eine Änderung annimmt. Wer die Bash versteht und bedient, statt sich nur durchzuklicken, macht sich am Ende das Leben leichter.
Das Setup
1. Voraussetzungen installieren
Auf openSUSE Tumbleweed reicht ein Befehl für alles, was gebraucht wird – Neovim selbst, Git für den Plugin-Manager, Node.js/npm für den Bash-Language-Server, Go für gopls, und ripgrep, das Telescope für die Fuzzy-Suche braucht:
sudo zypper install neovim git nodejs npm go ripgrep
2. Config-Verzeichnis anlegen
mkdir -p ~/.config/nvim
Neovim liest seine Konfiguration aus ~/.config/nvim/init.lua.
3. Plugin-Manager und Plugins eintragen
Pures Neovim, so wie man es installiert, bringt erstmal nichts mit – kein Plugin-Manager, keine vorgefertigte Config. Das ist der Unterschied zu fertigen "Distributionen" wie LazyVim oder NvChad, die ein komplettes Setup mit Plugins schon mitliefern. Ich hab mich für den eigenen Weg entschieden, weil ich gerne rumprobiere.
Standard-Plugin-Manager dafür ist lazy.nvim, eingetragen in ~/.config/nvim/init.lua. Die Config bringt mit:
- lazy.nvim als Plugin-Manager (bootstrapped sich beim ersten Start selbst)
- LSP für Go (
gopls) und Bash (bashls) – die Server-Binaries installiertmason.nvimzusammen mitmason-lspconfig.nvim, nvim-lspconfig übernimmt danach die eigentliche Anbindung an den Editor - Treesitter für Syntax-Highlighting (Go, Bash, Lua, Markdown)
- nvim-cmp für Autovervollständigung
- Telescope für Fuzzy-Suche
- nvim-tree als Dateibaum
- CodeCompanion.nvim für die KI-Integration
Der LSP-Teil gehört in den config-Block des nvim-lspconfig-Eintrags, also innerhalb von require("lazy").setup({ ... }):
{
"neovim/nvim-lspconfig",
config = function()
local capabilities = require("cmp_nvim_lsp").default_capabilities()
vim.lsp.config("gopls", {
capabilities = capabilities,
settings = {
gopls = {
gofumpt = true,
staticcheck = true,
},
},
})
vim.lsp.config("bashls", {
capabilities = capabilities,
})
vim.lsp.enable({ "gopls", "bashls" })
end,
}
Nachlesen lässt sich das direkt in Neovim selbst mit :help lsp-config, oder in der Doku von nvim-lspconfig – dort steht auch, welche Settings die einzelnen Language Server (gopls, bashls, …) jeweils akzeptieren.
4. Neovim starten und LSPs installieren
Nach dem ersten Start installiert Lazy alle Plugins automatisch. Danach in Neovim mit :Mason prüfen, ob gopls und bash-language-server installiert sind – falls nicht, darauf navigieren und i drücken.
Die KI-Anbindung: CodeCompanion.nvim
Der entscheidende Teil ist der openai_compatible-Adapter von CodeCompanion. Er spricht nicht mit einem bestimmten Anbieter, sondern mit jedem Server, der die OpenAI-API-Konventionen einhält – Basis-URL, /v1/chat/completions, /v1/models. Für mich sieht das so aus:
mein_llm = function()
return require("codecompanion.adapters").extend("openai_compatible", {
env = {
url = "https://llm.aihosting.mittwald.de",
chat_url = "/v1/chat/completions",
models_endpoint = "/v1/models",
api_key = "MITTWALD_LLM_API_KEY", -- Name der Umgebungsvariable, kein Klartext-Key
},
schema = {
model = {
default = "mein-modell-name",
},
},
})
end,
Der API-Key kommt als Umgebungsvariable:
echo 'export MITTWALD_LLM_API_KEY="dein-token-hier"' >> ~/.bashrc
source ~/.bashrc
Welche Modelle der Endpunkt anbietet, lässt sich vorher abfragen:
curl -s https://llm.aihosting.mittwald.de/v1/models \
-H "Authorization: Bearer $MITTWALD_LLM_API_KEY" | jq
Wer einen anderen Anbieter nutzt oder einen eigenen Server über vLLM betreibt: nur url und model anpassen, der Rest bleibt gleich.
Im Alltag
Im Chat-Fenster lässt sich der Dateiinhalt des aktuell offenen Buffers mit #{buffer} als Kontext mitschicken, ohne Code manuell reinzukopieren. Bei Aktionen, die etwas verändern, fragt CodeCompanion vorher nach:
Please select an option:
- g1 - Always accept
- g2 - Accept
- g3 - Reject
- g4 - Cancel
Das sind Tastenkombinationen im Normal-Modus, keine Texteingabe: g gefolgt von der Zahl. Für den Anfang lohnt sich g2 (einmal erlauben) statt gleich g1 (immer erlauben) – dann sieht man erstmal, was das Tool tatsächlich tut, bevor man ihm dauerhaft freie Hand gibt.
Für direkte Änderungen im Code, ohne den Umweg über den Chat, gibt's das Inline-Editieren:
<leader>ci
Mit vorheriger Auswahl (v + Bewegung) bezieht sich das gezielt auf den markierten Codeabschnitt. Das Modell schreibt dann direkt in den Buffer – kein separates Diff-Fenster, aber jede Änderung lässt sich ganz normal mit u rückgängig machen.
Warum das wichtig ist
Man sollte immer neugierig sein und dazulernen, Fehler machen, finden und ausbessern. Mir gefällt der Fokus auf Bash extrem. Andere brauchen eine grafische Oberfläche – jeder kann sich das Werkzeug nehmen, das ihm entspricht.