Neovim als IDE mit KI-Anbindung
Neovim von Grund auf als IDE eingerichtet: Plugin-Manager, LSP für Go und Bash, dazu eine KI-Anbindung über CodeCompanion.nvim, die per openai_compatible-Adapter mit jedem OpenAI-kompatiblen Server spricht – egal ob gehosteter Endpunkt oder selbst betrieben über vLLM.
Den Hintergrund und meine Gedanken dazu – warum Neovim, warum anbieterunabhängig – gibt's im Blogeintrag Vim-Gewohnheit, KI daneben. Hier nur die reine Anleitung zum Nachbauen.
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 bringt kein Plugin-Manager mit. Standard dafür ist lazy.nvim, eingetragen in ~/.config/nvim/init.lua:
-- Bootstrap lazy.nvim
local lazypath = vim.fn.stdpath("data") .. "/lazy/lazy.nvim"
if not vim.loop.fs_stat(lazypath) then
vim.fn.system({
"git", "clone", "--filter=blob:none",
"https://github.com/folke/lazy.nvim.git",
"--branch=stable",
lazypath,
})
end
vim.opt.rtp:prepend(lazypath)
require("lazy").setup({
{ "neovim/nvim-lspconfig" },
{ "mason-org/mason.nvim" },
{ "mason-org/mason-lspconfig.nvim" },
{ "hrsh7th/nvim-cmp" },
{ "hrsh7th/cmp-nvim-lsp" },
{ "nvim-treesitter/nvim-treesitter", build = ":TSUpdate" },
{ "nvim-telescope/telescope.nvim", dependencies = { "nvim-lua/plenary.nvim" } },
{ "nvim-tree/nvim-tree.lua" },
{ "olimorris/codecompanion.nvim", dependencies = { "nvim-lua/plenary.nvim", "nvim-treesitter/nvim-treesitter" } },
})
Drei der Plugins brauchen noch eine minimale eigene Config, sonst tun sie nichts. Kommt ebenfalls in die init.lua:
-- Mason installiert die eigentlichen LSP-Server-Binaries (gopls, bash-language-server).
-- mason-lspconfig verbindet das mit nvim-lspconfig und lädt bei Bedarf automatisch nach.
require("mason").setup()
require("mason-lspconfig").setup({
ensure_installed = { "gopls", "bashls" },
})
-- nvim-cmp: ohne diese Config zeigt der Editor keine Vervollständigungs-Vorschläge an
local cmp = require("cmp")
cmp.setup({
mapping = cmp.mapping.preset.insert({
["<CR>"] = cmp.mapping.confirm({ select = true }),
["<Tab>"] = cmp.mapping.select_next_item(),
}),
sources = {
{ name = "nvim_lsp" },
},
})
-- nvim-tree: Taste zum Ein-/Ausblenden des Dateibaums
vim.keymap.set("n", "<leader>e", ":NvimTreeToggle<CR>", { desc = "Dateibaum umschalten" })
4. LSP konfigurieren
Der LSP-Teil gehört in den config-Block des nvim-lspconfig-Eintrags:
{
"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,
}
Details zu den Settings der einzelnen Language Server: :help lsp-config in Neovim, oder die Doku von nvim-lspconfig.
5. Neovim starten
Nach dem ersten Start installiert Lazy alle Plugins automatisch, mason-lspconfig lädt dank ensure_installed direkt gopls und bash-language-server nach. Zur Kontrolle in Neovim :Mason öffnen – dort sollten beide mit einem grünen Häkchen stehen. Falls nicht, draufnavigieren und i drücken.
KI-Anbindung: CodeCompanion.nvim
Der openai_compatible-Adapter spricht mit jedem Server, der die OpenAI-API-Konventionen einhält – Basis-URL, /v1/chat/completions, /v1/models:
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,
Wichtig: api_key bekommt hier den Namen der Umgebungsvariable, nicht den Key selbst als Klartext. CodeCompanion löst das intern auf und liest den tatsächlichen Wert zur Laufzeit aus der Shell-Umgebung.
Der API-Key landet nicht in der Config:
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
Anderer Anbieter oder eigener Server über vLLM: nur url und model anpassen, der Rest bleibt gleich. Man kann auch magische Weichen bauen, das habe ich aber noch nicht getestet.
Bedienung
#{buffer}im Chat-Fenster schickt den Inhalt des aktuell offenen Buffers als Kontext mit.- Bei Änderungen fragt CodeCompanion nach:
g1(immer erlauben),g2(einmal erlauben),g3(ablehnen),g4(abbrechen) – Tastenkombination im Normal-Modus,ggefolgt von der Zahl. Details dazu in der CodeCompanion-Doku. <leader>cieditiert inline direkt im Buffer, mit vorheriger Auswahl (v+ Bewegung) gezielt auf den markierten Codeabschnitt. Änderungen lassen sich miturückgängig machen.