-- ---------------------------- -- Basic Neovim Settings -- ---------------------------- vim.opt.number = true -- Zeilennummern anzeigen vim.opt.relativenumber = true -- Relative Zeilennummern vim.opt.mouse = 'a' -- Maus aktivieren vim.opt.ignorecase = true -- Groß-/Kleinschreibung bei Suche ignorieren vim.opt.smartcase = true -- Außer bei Großbuchstaben in Suche vim.opt.wrap = false -- Kein automatischer Zeilenumbruch vim.opt.breakindent = true -- Einrückung bei umbrechenden Zeilen vim.opt.tabstop = 4 -- Tab = 4 Leerzeichen vim.opt.shiftwidth = 4 -- Einrückung = 4 Leerzeichen vim.opt.expandtab = true -- Tabs zu Leerzeichen konvertieren vim.opt.termguicolors = true -- 24-bit Farben vim.opt.updatetime = 300 -- Schnellere Aktualisierung vim.opt.signcolumn = 'yes' -- Immer Spalte für Zeichen anzeigen vim.opt.cursorline = true -- Aktuelle Zeile hervorheben vim.opt.scrolloff = 8 -- 8 Zeilen Abstand beim Scrollen vim.opt.sidescrolloff = 8 -- 8 Zeichen Abstand horizontal -- Encoding vim.opt.encoding = 'utf-8' vim.opt.fileencoding = 'utf-8' -- Clipboard (System-Zwischenablage nutzen) vim.opt.clipboard = 'unnamedplus' -- Keybindings Leader-Key vim.g.mapleader = ' ' -- Space als Leader-Taste -- ---------------------------- -- Load lazy.nvim (plugin manager) -- ---------------------------- 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) -- ---------------------------- -- Plugins -- ---------------------------- require("lazy").setup({ -- Colorscheme { "catppuccin/nvim", name = "catppuccin", priority = 1000, config = function() vim.cmd.colorscheme("catppuccin-macchiato") end }, -- LaTeX support (VimTeX) { "lervag/vimtex", lazy = false, init = function() -- PDF-Viewer vim.g.vimtex_view_method = "zathura" -- Compiler-Einstellungen vim.g.vimtex_compiler_method = "latexmk" vim.g.vimtex_compiler_latexmk = { build_dir = "build", callback = 1, continuous = 1, executable = "latexmk", options = { "-pdf", "-interaction=nonstopmode", "-synctex=1", "-file-line-error", }, } -- Automatische PDF-Aktualisierung vim.g.vimtex_view_automatic = 1 -- Fehler-Quickfix deaktivieren (nutze LSP stattdessen) vim.g.vimtex_quickfix_mode = 0 -- Syntax-Hervorhebung vim.g.vimtex_syntax_enabled = 1 vim.g.vimtex_syntax_conceal_disable = 0 -- Bessere Fehlerausgabe vim.g.vimtex_log_verbose = 0 end, config = function() -- Keybindings für VimTeX vim.keymap.set('n', 'll', 'VimtexCompile', { desc = 'LaTeX: Compile' }) vim.keymap.set('n', 'lv', 'VimtexView', { desc = 'LaTeX: View PDF' }) vim.keymap.set('n', 'lc', 'VimtexClean', { desc = 'LaTeX: Clean' }) vim.keymap.set('n', 'le', 'VimtexErrors', { desc = 'LaTeX: Errors' }) vim.keymap.set('n', 'lt', 'VimtexTocOpen', { desc = 'LaTeX: TOC' }) vim.keymap.set('n', 'lk', 'VimtexStop', { desc = 'LaTeX: Stop' }) end }, -- Markdown Rendering (NEU!) { 'MeanderingProgrammer/render-markdown.nvim', dependencies = { 'nvim-treesitter/nvim-treesitter', 'nvim-tree/nvim-web-devicons' }, ft = { 'markdown' }, -- Lädt nur bei Markdown-Dateien config = function() require('render-markdown').setup({ -- Optionale Einstellungen: file_types = { 'markdown' }, -- Headings mit Icons heading = { enabled = true, sign = true, icons = { '󰲡 ', '󰲣 ', '󰲥 ', '󰲧 ', '󰲩 ', '󰲫 ' }, }, -- Code-Blöcke hervorheben code = { enabled = true, sign = true, style = 'full', }, -- Checklisten checkbox = { enabled = true, unchecked = { icon = '󰄱 ' }, checked = { icon = '󰱒 ' }, }, }) -- Toggle-Keybinding für Markdown-Rendering vim.keymap.set('n', 'md', 'RenderMarkdown toggle', { desc = 'Toggle Markdown Render' }) end }, -- File Explorer { "nvim-tree/nvim-tree.lua", dependencies = { "nvim-tree/nvim-web-devicons" }, config = function() require("nvim-tree").setup({ view = { width = 30, side = "left", }, renderer = { icons = { show = { file = true, folder = true, folder_arrow = true, git = true, }, }, }, }) vim.keymap.set('n', 'e', 'NvimTreeToggle', { desc = 'Toggle File Explorer' }) -- Automatisch beim Start öffnen (NEU!) vim.api.nvim_create_autocmd("VimEnter", { callback = function() -- Nur öffnen, wenn keine Datei als Argument übergeben wurde if vim.fn.argc() == 0 then require("nvim-tree.api").tree.open() end end }) end }, -- Statusline (zeigt Pfad, Modus, etc.) { "nvim-lualine/lualine.nvim", dependencies = { "nvim-tree/nvim-web-devicons" }, config = function() require('lualine').setup({ options = { theme = 'catppuccin', component_separators = '|', section_separators = '', }, sections = { lualine_a = {'mode'}, lualine_b = {'branch', 'diff', 'diagnostics'}, lualine_c = {{'filename', path = 1}}, -- Zeigt relativen Pfad lualine_x = {'encoding', 'fileformat', 'filetype'}, lualine_y = {'progress'}, lualine_z = {'location'} }, }) end }, -- Fuzzy Finder (Dateien schnell finden) { "nvim-telescope/telescope.nvim", dependencies = { "nvim-lua/plenary.nvim" }, config = function() require('telescope').setup({ defaults = { file_ignore_patterns = { "build/", "%.aux", "%.bbl", "%.bcf", "%.blg", "%.fdb_latexmk", "%.fls", "%.log", "%.out", "%.synctex.gz", "%.toc" } } }) local builtin = require('telescope.builtin') 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' }) vim.keymap.set('n', 'fh', builtin.help_tags, { desc = 'Help Tags' }) end }, -- Better syntax highlighting { "nvim-treesitter/nvim-treesitter", build = ":TSUpdate", config = function() require("nvim-treesitter.configs").setup({ -- Nur Parser installieren, die KEINE tree-sitter CLI brauchen ensure_installed = { "lua", "python", "bash", "markdown", "markdown_inline" }, highlight = { enable = true }, indent = { enable = true }, }) end }, -- LSP (Language Server Protocol) { "neovim/nvim-lspconfig", dependencies = { "williamboman/mason.nvim", "williamboman/mason-lspconfig.nvim", "hrsh7th/cmp-nvim-lsp", }, config = function() require("mason").setup() require("mason-lspconfig").setup({ ensure_installed = { "texlab", "lua_ls" }, }) -- Capabilities für Autocomplete local capabilities = vim.lsp.protocol.make_client_capabilities() capabilities = require('cmp_nvim_lsp').default_capabilities(capabilities) -- TeXLab (LaTeX LSP) - Neue API vim.lsp.config.texlab = { default_config = { cmd = { 'texlab' }, filetypes = { 'tex', 'plaintex', 'bib' }, root_markers = { '.git', '.latexmkrc' }, settings = { texlab = { build = { executable = "latexmk", args = { "-pdf", "-interaction=nonstopmode", "-synctex=1", "%f" }, onSave = true, }, forwardSearch = { executable = "zathura", args = { "--synctex-forward", "%l:1:%f", "%p" }, }, } } } } vim.lsp.enable('texlab') -- Lua LSP - Neue API vim.lsp.config.lua_ls = { default_config = { cmd = { 'lua-language-server' }, filetypes = { 'lua' }, root_markers = { '.git' }, settings = { Lua = { diagnostics = { globals = {'vim'} }, workspace = { library = vim.api.nvim_get_runtime_file("", true), checkThirdParty = false, }, } } } } vim.lsp.enable('lua_ls') -- LSP Keybindings vim.keymap.set('n', 'gd', vim.lsp.buf.definition, { desc = 'Go to Definition' }) vim.keymap.set('n', 'K', vim.lsp.buf.hover, { desc = 'Hover Documentation' }) vim.keymap.set('n', 'rn', vim.lsp.buf.rename, { desc = 'Rename' }) vim.keymap.set('n', 'ca', vim.lsp.buf.code_action, { desc = 'Code Action' }) vim.keymap.set('n', 'gr', vim.lsp.buf.references, { desc = 'References' }) end }, -- Autocomplete { "hrsh7th/nvim-cmp", 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') cmp.setup({ snippet = { expand = function(args) luasnip.lsp_expand(args.body) end, }, mapping = cmp.mapping.preset.insert({ [''] = cmp.mapping.scroll_docs(-4), [''] = cmp.mapping.scroll_docs(4), [''] = cmp.mapping.complete(), [''] = cmp.mapping.abort(), [''] = 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 }, -- Git Integration { "lewis6991/gitsigns.nvim", config = function() require('gitsigns').setup() end }, -- Auto-pairs (automatische Klammern) { "windwp/nvim-autopairs", event = "InsertEnter", config = function() require('nvim-autopairs').setup({}) end }, -------------------------------------------- { "3rd/image.nvim", ft = { "markdown" }, -- Nur bei Markdown laden dependencies = { "nvim-treesitter/nvim-treesitter" }, config = function() require("image").setup({ backend = "kitty", -- oder "ueberzug" je nach Terminal integrations = { markdown = { enabled = true, only_render_image_at_cursor = false, filetypes = { "markdown", "vimwiki" }, }, }, }) end } -- Comment plugin { "numToStr/Comment.nvim", config = function() require('Comment').setup() end }, }) -- ---------------------------- -- Zusätzliche Keybindings -- ---------------------------- -- Buffer-Navigation vim.keymap.set('n', 'bn', 'bnext', { desc = 'Next Buffer' }) vim.keymap.set('n', 'bp', 'bprevious', { desc = 'Previous Buffer' }) vim.keymap.set('n', 'bd', 'bdelete', { desc = 'Delete Buffer' }) -- Window-Navigation vim.keymap.set('n', '', 'h', { desc = 'Window Left' }) vim.keymap.set('n', '', 'j', { desc = 'Window Down' }) vim.keymap.set('n', '', 'k', { desc = 'Window Up' }) vim.keymap.set('n', '', 'l', { desc = 'Window Right' }) -- Speichern & Beenden vim.keymap.set('n', 'w', 'w', { desc = 'Save' }) vim.keymap.set('n', 'q', 'q', { desc = 'Quit' }) -- Visual mode: Einrückung beibehalten vim.keymap.set('v', '<', '', '>gv')