-- ========================================================================== -- NEOVIM CONFIGURATION -- Clean & Stable (Fix for recent LSP updates) -- ========================================================================== -- ---------------------------- -- 1. Grundeinstellungen -- ---------------------------- vim.opt.number = true vim.opt.relativenumber = true vim.opt.mouse = 'a' vim.opt.ignorecase = true vim.opt.smartcase = true vim.opt.wrap = false vim.opt.breakindent = true vim.opt.tabstop = 4 vim.opt.shiftwidth = 4 vim.opt.expandtab = true vim.opt.termguicolors = true vim.opt.updatetime = 250 vim.opt.signcolumn = 'yes' vim.opt.cursorline = true vim.opt.scrolloff = 8 vim.opt.splitbelow = true vim.opt.splitright = true vim.opt.encoding = 'utf-8' vim.opt.clipboard = 'unnamedplus' vim.g.mapleader = ' ' vim.g.maplocalleader = ' ' -- ---------------------------- -- 2. Lazy.nvim Bootstrap -- ---------------------------- 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) -- ---------------------------- -- 3. Plugins -- ---------------------------- require("lazy").setup({ -- UI & Themes { "catppuccin/nvim", name = "catppuccin", priority = 1000, config = function() require("catppuccin").setup({ flavour = "macchiato" }) vim.cmd.colorscheme("catppuccin") end }, -- Noice (Hübsche UI) { "folke/noice.nvim", event = "VeryLazy", dependencies = { "MunifTanjim/nui.nvim", "rcarriga/nvim-notify" }, config = function() require("noice").setup({ lsp = { override = { ["vim.lsp.util.convert_input_to_markdown_lines"] = true, ["vim.lsp.util.stylize_markdown"] = true, ["cmp.entry.get_documentation"] = true, }, }, presets = { bottom_search = true, command_palette = true, long_message_to_split = true, }, }) end }, { "nvim-tree/nvim-web-devicons", lazy = true }, { "nvim-lualine/lualine.nvim", dependencies = { "nvim-tree/nvim-web-devicons" }, config = function() require('lualine').setup({ options = { theme = 'catppuccin' }, sections = { lualine_c = {{'filename', path = 1}} }, }) end }, { "folke/which-key.nvim", event = "VeryLazy", config = function() require("which-key").setup() end }, -- Navigation { "nvim-tree/nvim-tree.lua", cmd = { "NvimTreeToggle" }, config = function() require("nvim-tree").setup({ view = { width = 30 }, renderer = { group_empty = true }, }) end }, { "nvim-telescope/telescope.nvim", branch = "0.1.x", dependencies = { "nvim-lua/plenary.nvim" }, config = function() local builtin = require('telescope.builtin') require('telescope').setup({ defaults = { file_ignore_patterns = { "node_modules", ".git/" } } }) vim.keymap.set('n', 'ff', builtin.find_files, { desc = 'Find Files' }) vim.keymap.set('n', 'fg', builtin.live_grep, { desc = 'Live Grep' }) vim.keymap.set('n', 'fb', builtin.buffers, { desc = 'Find Buffers' }) end }, -- Syntax { "nvim-treesitter/nvim-treesitter", build = ":TSUpdate", event = { "BufReadPost", "BufNewFile" }, config = function() require("nvim-treesitter.configs").setup({ ensure_installed = { "lua", "python", "bash", "markdown", "markdown_inline", "vimdoc" }, highlight = { enable = true }, indent = { enable = true }, }) end }, { "windwp/nvim-autopairs", event = "InsertEnter", config = function() require('nvim-autopairs').setup({}) end }, { "lewis6991/gitsigns.nvim", event = { "BufReadPre", "BufNewFile" }, config = true }, -- == LSP & AUTOCOMPLETE (STABLE FIX) == { "neovim/nvim-lspconfig", dependencies = { "williamboman/mason.nvim", "williamboman/mason-lspconfig.nvim", "hrsh7th/cmp-nvim-lsp", }, config = function() require("mason").setup() local mason_lspconfig = require("mason-lspconfig") mason_lspconfig.setup({ ensure_installed = { "lua_ls" }, }) local capabilities = require('cmp_nvim_lsp').default_capabilities() local on_attach = function(_, bufnr) local opts = { buffer = bufnr, noremap = true, silent = true } vim.keymap.set('n', 'gd', vim.lsp.buf.definition, opts) vim.keymap.set('n', 'K', vim.lsp.buf.hover, opts) vim.keymap.set('n', 'rn', vim.lsp.buf.rename, opts) vim.keymap.set('n', 'ca', vim.lsp.buf.code_action, opts) end -- Hier nutzen wir setup_handlers. -- Das ist der sicherste Weg, um Fehler zu vermeiden. mason_lspconfig.setup_handlers({ -- Standard Handler für alle Server function(server_name) require("lspconfig")[server_name].setup({ capabilities = capabilities, on_attach = on_attach, }) end, -- Spezifischer Handler für Lua ["lua_ls"] = function() require("lspconfig").lua_ls.setup({ capabilities = capabilities, on_attach = on_attach, settings = { Lua = { diagnostics = { globals = {'vim'} } } } }) end, }) end }, { "hrsh7th/nvim-cmp", event = "InsertEnter", dependencies = { "hrsh7th/cmp-nvim-lsp", "hrsh7th/cmp-buffer", "hrsh7th/cmp-path", "L3MON4D3/LuaSnip", "saadparwaiz1/cmp_luasnip", }, config = function() local cmp = require('cmp') local luasnip = require('luasnip') require("luasnip").config.setup({ enable_autosnippets = true }) cmp.setup({ snippet = { expand = function(args) luasnip.lsp_expand(args.body) end, }, window = { completion = cmp.config.window.bordered(), documentation = cmp.config.window.bordered(), }, mapping = cmp.mapping.preset.insert({ [''] = cmp.mapping.scroll_docs(-4), [''] = cmp.mapping.scroll_docs(4), [''] = cmp.mapping.complete(), [''] = cmp.mapping.confirm({ select = true }), [''] = cmp.mapping(function(fallback) if cmp.visible() then cmp.select_next_item() elseif luasnip.expand_or_jumpable() then luasnip.expand_or_jump() else fallback() end end, { 'i', 's' }), [''] = cmp.mapping(function(fallback) if cmp.visible() then cmp.select_prev_item() elseif luasnip.jumpable(-1) then luasnip.jump(-1) else fallback() end end, { 'i', 's' }), }), sources = cmp.config.sources({ { name = 'nvim_lsp' }, { name = 'luasnip' }, { name = 'buffer' }, { name = 'path' }, }) }) end }, -- Markdown { "iamcco/markdown-preview.nvim", cmd = { "MarkdownPreviewToggle", "MarkdownPreview" }, ft = { "markdown" }, build = function() vim.fn["mkdp#util#install"]() end, keys = { { "mp", "MarkdownPreviewToggle", desc = "Markdown Preview" } } }, { "OXY2DEV/markview.nvim", ft = { "markdown" }, dependencies = { "nvim-treesitter/nvim-treesitter", "nvim-tree/nvim-web-devicons" }, }, -- Images (Fallback auf sicher) { "3rd/image.nvim", enabled = true, ft = { "markdown" }, dependencies = { "nvim-treesitter/nvim-treesitter" }, config = function() require("image").setup({ backend = "kitty", integrations = { markdown = { enabled = true, only_render_image_at_cursor = false, filetypes = { "markdown", "vimwiki" }, }, }, }) end }, }) -- Keybindings local keymap = vim.keymap.set keymap('n', 'e', 'NvimTreeToggle', { desc = 'Explorer Toggle' }) keymap('n', 'bn', 'bnext', { desc = 'Next Buffer' }) keymap('n', 'bp', 'bprevious', { desc = 'Prev Buffer' }) keymap('n', 'bd', 'bdelete', { desc = 'Close Buffer' }) keymap('n', '', 'h', { desc = 'Window Left' }) keymap('n', '', 'j', { desc = 'Window Down' }) keymap('n', '', 'k', { desc = 'Window Up' }) keymap('n', '', 'l', { desc = 'Window Right' }) keymap('n', 'w', 'w', { desc = 'Save File' }) keymap('n', 'q', 'q', { desc = 'Quit' }) keymap('n', '', 'nohlsearch', { desc = 'Clear Highlights' })